vs调试 SetUnhandledExceptionFilter MiniDumpWriteDump windbg

程序异常时, 调用MiniDumpWriteDump保存dump文件

配置编译选项, 生成pdb文件

pro:

LIBS += -LD:\\WinDDK\\7600.16385.1\\Debuggers\\sdk\\lib\\i386 -ldbghelp

main.cpp:

#include <QCoreApplication>
#include <windows.h>
#include <dbghelp.h>
#include <QDebug>
#include <QDateTime>
#include <QStringList>
#include <QString>

using namespace std;
using namespace Qt;

QString generate_dump_file(_EXCEPTION_POINTERS *ExceptionInfo)
{
    bool bDumpOK = false;
    DWORD dwProcessId = GetCurrentProcessId();
    DWORD dwThreadId = GetCurrentThreadId();

    QString dumpPath;
    {
        QStringList strList;

        strList << QString("dump");
        strList << QDateTime::currentDateTime().toString("yyyy-MM-dd_hh-mm-ss");
        strList << QString("ProcessId_%1").arg(dwProcessId);
        strList << QString("ThreadId_%1").arg(dwThreadId);
        strList << QString(".dmp");

        dumpPath = strList.join("__");
    }

    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProcessId);
    if (hProcess != INVALID_HANDLE_VALUE)
    {
        HANDLE hFile = CreateFile(reinterpret_cast<const wchar_t *>(dumpPath.utf16()), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
        if (hFile != INVALID_HANDLE_VALUE)
        {
            MINIDUMP_EXCEPTION_INFORMATION exception_information;
            exception_information.ThreadId = dwThreadId;
            exception_information.ExceptionPointers = ExceptionInfo;
            exception_information.ClientPointers = TRUE;
            bDumpOK = MiniDumpWriteDump(hProcess, dwProcessId, hFile, MiniDumpWithFullMemory, &exception_information, NULL, NULL);
            CloseHandle(hFile);
        }
    }

    return bDumpOK ? dumpPath : QString();
}

LONG WINAPI MyUnhandledExceptionFilter(
  _In_ struct _EXCEPTION_POINTERS *ExceptionInfo
)
{
    qDebug() << "Catch unhandled exception, Generating dump file...";
    QString dump_path = generate_dump_file(ExceptionInfo);
    qDebug() << "Done. Dump file path:";
    qDebug() << dump_path;

    return EXCEPTION_EXECUTE_HANDLER;
}

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    // 设置异常处理器
    SetUnhandledExceptionFilter(MyUnhandledExceptionFilter);

    // 制造异常
    *((int *) 0) = 0;

    return 0;
}

windbg, 分析dump文件, 得到调用堆栈

符号表路径设置

File -> Symbol File Path
pdb符号表文件所在的路径;C:\Symbols;SRV*C:\Symbols*http://msdl.microsoft.com/download/symbols
勾选"reload"

源代码路径设置

File -> Source File Path
源代码所在路径1;源代码所在路径2

打开dump文件

windbg -> File -> Open Crash Dump

执行分析命令

!analyze -v