2011-09-15 14 views
1

我發現了很多關於如何在需要時手動創建故障轉儲的帖子,但我想要做的是確保在受監視的應用程序崩潰時生成故障轉儲。如何在崩潰時觀察進程並生成小型轉儲程序(如PROCDUMP)?

TechNet PROCDUMP工具可以完美地完成此操作。我想知道的是,如何編寫一些代碼來在我自己的管理程序中執行相同的操作,以便在出現異常時只創建轉儲文件。

我的程序是一個服務應用程序,它知道我希望監視的程序的進程ID。

只是爲了澄清,我想模仿一下這個調用PROCDUMP會做:

procdump -e someprocess.exe -w

理論上的Windows應該能夠做這個工作對我來說與DrWatson。我遇到的問題是我有大約200個客戶系統在運行,這些系統聲稱我們的應用程序隨機崩潰。 Watson博士似乎並沒有證實我們的應用程序崩潰的事實,因此我決定讓我們自己的軟件控制崩潰轉儲。

我已經設法讓我自己的應用程序創建自己的轉儲使用__try/except和MiniDumpWriteDump()與MiniDumpWithFullMemory類型..但我不能看看局部變量等與WinDbg,所以我猜這個是因爲它是從應用程序本身內部觸發的..所以..另一個原因是我希望監視器/管理類型的應用程序能夠完成這項工作。

至少......一個應用程序如何對另一個應用程序崩潰做出反應?你是否必須安裝某種調試鉤子或假裝管理程序實際上是一個自定義調試器?

乾杯

回答

1

好吧,我想出了自己。我編寫了自己的「調試器」,可以捕獲我的「調試器」附加到的程序中生成的異常。現在我只需要弄清楚如何編寫該外部進程的小型轉儲。棘手的部分似乎是,我必須提供一個EXCEPTION_POINTERS數組......這是我現在需要弄清的唯一一點。

下面是一個示例代碼片段。我希望它可以幫助其他人在未來:

void WriteCrashDump(EXCEPTION_DEBUG_INFO *pExceptionInfo) 
{ 
    CONTEXT c; 

    memset(&c, 0, sizeof(c)); 

    GetThreadContext(hThread, &c); 

    EXCEPTION_POINTERS ep; 

    ep.ContextRecord = &c; 
    ep.ExceptionRecord = &pExceptionInfo->ExceptionRecord; 

    MINIDUMP_EXCEPTION_INFORMATION minidump_exception; 

    minidump_exception.ThreadId   = dwThreadId; 
    minidump_exception.ExceptionPointers = &ep; 
    minidump_exception.ClientPointers = true; 

    HANDLE hFile = CreateFile("dump.dmp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); 

    if(hFile) 
    { 
    BOOL fSuccess; 

    fSuccess = MiniDumpWriteDump(hProcess, dwProcessId, hFile, MiniDumpWithFullMemory, &minidump_exception, NULL, NULL); 

    if(! fSuccess) 
     printf("MiniDumpWriteDump -FAILED\n"); 

    CloseHandle(hFile); 
    } 
} 

void DebugLoop(void) 
{ 
    DEBUG_EVENT de; 

    while(1) 
    { 
    WaitForDebugEvent(&de, INFINITE); 

    switch(de.dwDebugEventCode) 
    { 
     case CREATE_PROCESS_DEBUG_EVENT: 
     hProcess = de.u.CreateProcessInfo.hProcess; 
     break; 

     case EXCEPTION_DEBUG_EVENT: 
     printf("EXCEPTION_DEBUG_EVENT\n"); 

     // PDS: Not interested in the fact that I have attached to it and caused a breakpoint.. 
     if(de.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT) 
      break; 

     dwProcessId = de.dwProcessId; 
     dwThreadId = de.dwThreadId; 

     WriteCrashDump(&de.u.Exception); 
     return; 

     default: 
     break; 
    } 

    ContinueDebugEvent(de.dwProcessId, de.dwThreadId, DBG_CONTINUE); 
    } 
} 
相關問題