2012-01-26 35 views
7

Tôi đang cố gắng tạo tệp kết xuất cho ứng dụng của mình bất cứ khi nào nó gặp sự cố. Tôi hiện đang sử dụng procdump.exe với cờ -e để làm điều đó, vì vậy nếu tôi có ngoại lệ unhandled trong procdump ứng dụng của tôi tạo ra một tệp kết xuất cho tôi.Tạo tệp kết xuất cho một ứng dụng bất cứ khi nào nó gặp sự cố

Tôi nghĩ rằng tôi đã hoàn thành, nhưng sau đó tôi phát hiện ra rằng ứng dụng của tôi bị treo và procdump không tạo tệp kết xuất. Sau khi một số điều tra tôi đã phát hiện ra rằng việc sử dụng không hợp lệ của vector :: phía trước gây ra lỗi thời gian chạy. Tôi bật cờ _SECURE_SCL_THROWS và sau đó procdump.exe -e đã bắt gặp sự cố và tạo tệp kết xuất.

Bây giờ cho câu hỏi của tôi: Hiện tại procdump.exe -e sẽ luôn tạo tệp kết xuất khi ứng dụng của tôi gặp sự cố? Làm cách nào để đảm bảo rằng tôi không có bất kỳ tình huống nào khác mà procdump -e không tốt cho tôi?

Trả lời

7

Tôi cho rằng bạn đang ở trong môi trường cửa sổ (vì bạn sử dụng procdump.exe). Bạn cũng có thể thiết lập một bộ lọc ngoại lệ cho programm của bạn mà viết một mindump bất cứ khi nào tai nạn ứng dụng của bạn:

  1. Đăng ký một hàm callback sử dụng SetUnhandledExceptionFilter mà sẽ được gọi vào một vụ tai nạn. Một chữ ký có thể sẽ là:

    LONG WINAPI HandleException(struct _EXCEPTION_POINTERS* apExceptionInfo) 
    

    đăng ký nó ở đâu đó sử dụng:

    SetUnhandledExceptionFilter(HandleException); 
    
  2. Định nghĩa một con trỏ hàm để gọi hàm 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. Sử dụng MiniDumpWriteDump chức năng để viết bãi chứa (yêu cầu DbgHelp.dll 5.1 hoặc mới hơn) trong phương thức gọi lại registerd trước đây (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

Tại sao bạn sử dụng 'GetProcAddr' cho' MiniDumpWriteDump' khi bạn có thể chỉ cần bao gồm DbgHelp.h từ DebuggingTools SDK ?? –

+0

Vì IAT (Bảng địa chỉ nhập) có thể đã bị hỏng khi xảy ra sự cố. Trong các trình xử lý sự cố như vậy, điều đáng tin cậy duy nhất cần thực hiện là liên kết với các thư viện của chính bạn! –

+0

@ ПетърПетров Nhưng sau đó làm thế nào bạn sẽ gọi 'LoadLibrary'? Nếu IAT bị hỏng, thì có thể bạn đã bị say. – 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; 
}