2017-04-03 6 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()を使用してクラッシュダンプを作成できます。 ExceptionParamにはNULLを渡すだけです。ここで

が役立つかもしれないいくつかのコードです:

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

私は[これを]試しました(http://ntcoder.com/bab/2014/10/14/how-to-create-full-memory-dumps-minidumpwritedump /を使用して)ダンプファイルを作成しましたが、ベースEBPポインタは0x00000であり、関数。あなたのコードを見ていますが、 'DllLoader'は何ですか?ありがとう。 – zar

+0

DllLoaderは ':: LoadLibrary()'のラッパーです。特にない。 –

+0

@zar:そのコードはプロセス外からクラッシュダンプを作成することになっています。非常に長時間実行されていないか、ハングしていない限り、コールスタックに関数を持たせることは幸運なことです。 –

関連する問題