2017-04-03 53 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-crash –

回答

2

是的,當然。類似的Windows任務管理器可以創建正在運行/掛起的應用程序的崩潰轉儲,無任何例外情況,您可以使用MiniDumpWriteDump()來創建崩潰轉儲。只需通過NULL即可獲得ExceptionParam

下面是一些代碼,可以幫助:

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:該代碼應該創建一個進程外的崩潰轉儲。只要運行時間不長或掛起,您就必須很幸運才能在調用堆棧上使用您的功能。 –

相關問題