2017-04-03 13 views
1

원격 사이트에 드문 오류가 발생하지만 응용 프로그램을 중단시키지 않는다고 가정하십시오. 이 문제가 발생하면 미니 덤프 파일을 만들고 싶습니다. 따라서 주로 호출 스택과 함께 작업 할 몇 가지 정보가 있습니다.충돌없이 프로그래밍 방식으로 미니 덤프 파일을 만들 수 있습니까?

의사 코드는 다음입니다 :

try 
{ 
    doStuff(); 
} 
catch(_com_error &e) 
{ 
    make_minidump(); // is this possible? 

    dump_com_error(e); 
    return FALSE; 
} 

내가 보는 모든 예제

내가 덤프 파일을 생성 (데모 목적 이상을 위해) 충돌 응용 프로그램을 야기 할 것이다하지만 난 싶지 않아 필요 그렇게. 이렇게 덤프 파일을 만들 수 있습니까?

나는 작업 관리자로 가서 실행중인 프로세스의 덤프 파일을 만들 수 있으며 마찬가지로 ProcessExplorer을 사용하여 동일한 결과를 얻을 수 있으므로 가능한 것이 좋습니다.

동시에 모든 예제에서 덤프 파일은 컨트롤이 응용 프로그램이 충돌 할 때 호출되는 SetUnhandledExceptionFilter이 될 때 생성됩니다!

마지막 수단으로 생성 된 덤프 파일을 얻는 유일한 방법은 다음과 같이 의도적으로 응용 프로그램을 중단하는 것입니다. 이 사건의 원인이 무엇인지 알기 때문이죠.

LONG CALLBACK unhandled_handler(EXCEPTION_POINTERS* e) 
{ 
    make_minidump(e); 
    return EXCEPTION_CONTINUE_SEARCH; 
} 

int main() 
{ 
    SetUnhandledExceptionFilter(unhandled_handler); 

    return *(int*)0; 
} 
+3

https : //로 MSDN을. microsoft.com/en-us/library/windows/desktop/ms680360(v=vs.85).aspx –

+0

가능한 복제본 (2009 년으로 표시되지 않음) http://stackoverflow.com/questions/1547211/how-to -create-minidump-for-my-process-when-it-crashes –

답변

2

예, 물론입니다. Windows 작업 관리자와 마찬가지로 예외없이 실행중인/정지중인 응용 프로그램의 크래시 덤프를 만들 수 있으므로 MiniDumpWriteDump()을 사용하여 크래시 덤프를 만들 수 있습니다. ExceptionParamNULL을 전달하십시오.

여기에 도움이 될 몇 가지 코드입니다 :

typedef BOOL (WINAPI *MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, 
     MINIDUMP_TYPE DumpType, 
     CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, 
     CONST PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, 
     CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam 
             ); 

const wchar_t * DBGHELP = L"DbgHelp.dll"; 

bool Dump(const std::wstring & dumpFile) 
{ 
    bool success = false; 
    DllLoader loader; 

    // Load dbghelp.dll. Try first to find it in the application directory. 
    loader.Load(::GetModuleHandle(NULL), DBGHELP); 
    if (!loader.IsLoaded()) 
    { 
     loader.Load(DBGHELP); 
    } 

    if (loader.IsLoaded()) 
    { 
     MINIDUMPWRITEDUMP pDump = MINIDUMPWRITEDUMP(loader.GetProcAddress("MiniDumpWriteDump")); 

     if (pDump) 
     { 
      // Create dump file 
      HANDLE fileHandle = ::CreateFileW(dumpFile.c_str(), GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, CREATE_ALWAYS, 
               FILE_ATTRIBUTE_NORMAL, nullptr); 

      if (fileHandle != INVALID_HANDLE_VALUE) 
      { 
       BOOL bOK = pDump(GetCurrentProcess(), GetCurrentProcessId(), fileHandle, MiniDumpWithFullMemory, nullptr, nullptr, nullptr); 
       if (bOK) 
       { 
        success = true; 
       } 

       ::CloseHandle(fileHandle); 
      } 
     } 
    } 

    return success; 
} 

때문에 최적화에, 나는 k 올바른 스택을 볼 수 있지만, dds ebp 그것을 보여

0029f8d0 01302029 GetCrashWithDLL!MethodB+0x99 [f:\...\getcrashwithdll.cpp @ 12] 
[...] 
0029f914 0130209c GetCrashWithDLL!wmain+0x3c [f:\...\getcrashwithdll.cpp @ 31] 
[...] 
0029f920 01302cff GetCrashWithDLL!__tmainCRTStartup+0xfd [f:\dd\vctools\crt\crtw32\dllstuff\crtexe.c @ 623] 
+0

나는 [this] (http://ntcoder.com)을 시도했다./bab/2014/10/14/how-to-create-full-memory-dumps-using-minidumpwritedump /)를 사용하여 덤프 파일을 만들었지 만 기본 EBP 포인터는 0x00000이고 내 기능. 나는 당신의 코드를보고 있지만'DllLoader'가 무엇인지 확실하지 않습니까? 감사. – zar

+0

DllLoader는'LoadLibrary()'주위의 래퍼 일뿐입니다. 특별한 것은 없습니다. –

+0

@zar :이 코드는 프로세스 외부에서 크래시 덤프를 생성합니다. 너는 오래 걸리거나 매달리지 않는 한 호출 스택에 함수를 가지려면 운이 좋을 필요가있다. –