2012-01-26 15 views
7

Próbuję utworzyć plik zrzutu dla mojej aplikacji, gdy wystąpi awaria. Obecnie używam procdump.exe z flagą -e, aby to zrobić, więc jeśli mam nieobsługiwany wyjątek w mojej aplikacji, procdump tworzy dla mnie plik zrzutu.Utwórz plik zrzutu dla aplikacji, gdy wystąpi awaria.

Myślałem, że skończyłem, ale potem dowiedziałem się, że moja aplikacja się zawiesza, a procdump nie tworzy pliku zrzutu. Po pewnych badaniach odkryłem, że nieprawidłowe użycie wektora :: front powoduje błąd runtime. Włączyłem flagę _SECURE_SCL_THROWS, a po tym procdump.exe -e przechwyciłem awarię i utworzyłem plik zrzutu.

Teraz na moje pytanie: czy teraz procdump.exe -e zawsze tworzy plik zrzutu, gdy moja aplikacja ulega awarii? Jak mogę zagwarantować, że nie mam żadnych innych scenariuszy, w których procdump -e nie jest dla mnie dobry?

Odpowiedz

7

Zakładam, że jesteś w środowisku Windows (ponieważ używasz procdump.exe). Można także ustawić filtr wyjątku dla programowo że pisze mindump zawsze, gdy awaria aplikacji:

  1. Rejestruje funkcję zwrotną przy użyciu SetUnhandledExceptionFilter która zostanie wywołana na zderzenia. Ewentualny podpis będzie:

    LONG WINAPI HandleException(struct _EXCEPTION_POINTERS* apExceptionInfo) 
    

    zarejestrować go gdzieś przy użyciu:

    SetUnhandledExceptionFilter(HandleException); 
    
  2. Zdefiniuj wskaźnik funkcji do wywołania funkcji MiniDumpWriteDump:

    typedef BOOL (WINAPI *MINIDUMPWRITEDUMP)(HANDLE hProcess, DWORD dwPid, HANDLE hFile, MINIDUMP_TYPE DumpType,CONST PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,CONSTPMINIDUMP_USER_STREAM_INFORMATIOUserStreamParam,CONST PMINIDUMP_CALLBACK_INFORMATION CallbackParam); 
    
  3. użyć funkcji MiniDumpWriteDump napisać zrzut (wymaga programu DbgHelp.dll 5.1 lub nowszego) w poprzednio zarejestrowanej metodzie wywołania zwrotnego (HandleException):

    HMODULE mhLib = ::LoadLibrary(_T("dbghelp.dll")); 
    MINIDUMPWRITEDUMP pDump = (MINIDUMPWRITEDUMP)::GetProcAddress(mhLib, "MiniDumpWriteDump"); 
    
    HANDLE hFile = ::CreateFile(_T("dump_name"), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 
            FILE_ATTRIBUTE_NORMAL, NULL); 
    
    
    _MINIDUMP_EXCEPTION_INFORMATION ExInfo; 
    ExInfo.ThreadId = ::GetCurrentThreadId(); 
    ExInfo.ExceptionPointers = apExceptionInfo; 
    ExInfo.ClientPointers = FALSE; 
    
    pDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL); 
    ::CloseHandle(hFile); 
    
+0

Dlaczego używasz 'GetProcAddr' dla' MiniDumpWriteDump', kiedy możesz po prostu włącz DbgHelp.h z Debugging Tool Kit? –

+0

Ponieważ IAT (Import Address Table) może być już uszkodzony po wystąpieniu awarii. W takich urządzeniach ratunkowych jedyną niezawodną rzeczą jest samodzielne łączenie się z bibliotekami! –

+0

@ ПетърПетров Ale jak nazwać "LoadLibrary"? Jeśli IAT jest uszkodzony, prawdopodobnie jesteś już spieprzony. – LHLaurini

2

/* WinDump.cpp */

#ifdef WIN32 

#include <windows.h> 
#include <Dbghelp.h> 
#include <tchar.h> 


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); 

void create_minidump(struct _EXCEPTION_POINTERS* apExceptionInfo) 
{ 
    HMODULE mhLib = ::LoadLibrary(_T("dbghelp.dll")); 
    MINIDUMPWRITEDUMP pDump = (MINIDUMPWRITEDUMP)::GetProcAddress(mhLib, "MiniDumpWriteDump"); 

    HANDLE hFile = ::CreateFile(_T("core.dmp"), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 
     FILE_ATTRIBUTE_NORMAL, NULL); 

    _MINIDUMP_EXCEPTION_INFORMATION ExInfo; 
    ExInfo.ThreadId = ::GetCurrentThreadId(); 
    ExInfo.ExceptionPointers = apExceptionInfo; 
    ExInfo.ClientPointers = FALSE; 

    pDump(GetCurrentProcess(), GetCurrentProcessId(), hFile, MiniDumpNormal, &ExInfo, NULL, NULL); 
    ::CloseHandle(hFile); 
} 

LONG WINAPI unhandled_handler(struct _EXCEPTION_POINTERS* apExceptionInfo) 
{ 
    create_minidump(apExceptionInfo); 
    return EXCEPTION_CONTINUE_SEARCH; 
} 

#endif // WIN32 

/* WinDump.h */

#ifdef WIN32 

LONG WINAPI unhandled_handler(struct _EXCEPTION_POINTERS* apExceptionInfo); 

#endif // WIN32 

/* main.cpp */

#include "WinDump.h" 

int main(int argc, char **argv) 
{ 

    // Create a dump file whenever the gateway crashes only on windows 
    SetUnhandledExceptionFilter(unhandled_handler); 
    return 0; 
} 
Powiązane problemy