C++ 每当应用程序崩溃时,为其创建转储文件

C++ 每当应用程序崩溃时,为其创建转储文件,c++,visual-studio-2008,std,crash-dumps,minidump,C++,Visual Studio 2008,Std,Crash Dumps,Minidump,每当我的应用程序崩溃时,我都试图为它创建一个转储文件。 我目前正在使用带有-e标志的procdump.exe来执行此操作,因此,如果我的应用程序中存在未处理的异常,procdump将为我创建一个转储文件 我以为我已经完成了,但后来我发现我的应用程序崩溃了,procdump没有创建转储文件。经过一些调查,我发现vector::front的无效使用会导致运行时错误。我打开了_SECURE_SCL_THROWS标志,然后procdump.exe-e捕捉到了崩溃并创建了一个转储文件 现在我的问题是:当我

每当我的应用程序崩溃时,我都试图为它创建一个转储文件。 我目前正在使用带有-e标志的procdump.exe来执行此操作,因此,如果我的应用程序中存在未处理的异常,procdump将为我创建一个转储文件

我以为我已经完成了,但后来我发现我的应用程序崩溃了,procdump没有创建转储文件。经过一些调查,我发现vector::front的无效使用会导致运行时错误。我打开了_SECURE_SCL_THROWS标志,然后procdump.exe-e捕捉到了崩溃并创建了一个转储文件


现在我的问题是:当我的应用程序崩溃时,procdump.exe-e是否总是创建一个转储文件?我如何保证没有任何其他procdump-e对我不利的场景?

我假设您在windows环境中(因为您使用的是procdump.exe)。您还可以为您的程序设置一个异常过滤器,该程序在应用程序崩溃时编写mindump

  • 注册一个回调函数,在崩溃时使用该函数调用。可能的签名是:

    LONG WINAPI HandleException(struct _EXCEPTION_POINTERS* apExceptionInfo)
    
    使用以下方法在某处注册:

    SetUnhandledExceptionFilter(HandleException);   
    
  • 定义调用函数的函数指针:

  • 使用该函数在先前的registerd回调方法(HandleException)中写入转储(需要DbgHelp.dll 5.1或更高版本):

  • /*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
    
    /*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;
    }
    

    当您可以从DebuggingTools SDK中包含DbgHelp.h时,为什么要使用
    GetProcAddr
    进行
    minidumpWriteDomainp
    ,因为发生崩溃时IAT(导入地址表)可能已经损坏。在这种崩溃处理程序中,唯一可靠的方法就是自己链接库@那你怎么调用加载库呢?如果IAT已损坏,那么您可能已经完蛋了。有时IAT不会损坏,但win32子系统上的其他内部状态会损坏,例如CreateFileA/W将不工作,但LoadLibrary通常工作。如果IAT已损坏,它将立即崩溃。我注意到,当IAT在x64 win7上损坏时,kernel32.dll函数可以工作。。。这很奇怪。
    #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
    
    #ifdef WIN32
    
    LONG WINAPI unhandled_handler(struct _EXCEPTION_POINTERS* apExceptionInfo);
    
    #endif // WIN32
    
    #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;
    }