12

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

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

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

4

3 回答 3

14

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

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

    LONG WINAPI HandleException(struct _EXCEPTION_POINTERS* apExceptionInfo)
    

    使用以下方式在某处注册:

    SetUnhandledExceptionFilter(HandleException);   
    
  2. 定义一个函数指针来调用函数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. 使用MiniDumpWriteDump函数在之前注册的回调方法(HandleException)中写入转储(需要 DbgHelp.dll 5.1 或更高版本):

    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);
    
于 2012-01-26T15:46:38.457 回答
10

/* 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;
}
于 2014-08-22T08:04:21.117 回答
1

或者使用 Windows 的内置错误报告 WER,通过向注册表添加一个键,为您的应用启用它。更多详细信息:https ://docs.microsoft.com/en-us/windows/win32/wer/collecting-user-mode-dumps

于 2021-10-15T18:44:47.053 回答