在Windows平台的C++程序开发中,程序崩溃后如果没有对应的Dump文件,排查问题会非常困难。MiniDump是Windows系统提供的一种轻量级Dump格式,能够记录程序崩溃时的关键信息,且生成的文件体积较小,适合日常调试使用。

生成Dump文件的核心原理
Windows系统提供了DbgHelp.dll动态库,其中包含MiniDumpWriteDump函数,专门用于生成MiniDump文件。要自动生成崩溃时的Dump,核心步骤是:先捕获程序的异常信号,在异常处理函数中调用MiniDumpWriteDump接口,将当前进程的崩溃信息写入到指定的Dump文件中。
异常捕获的实现方式
Windows下可以通过SetUnhandledExceptionFilter函数设置未处理异常过滤器,当程序发生未捕获的异常时,系统会调用我们设置的回调函数,在这个回调函数中就可以执行Dump文件的写入逻辑。
回调函数定义
未处理异常回调函数的格式是固定的,返回值是LONG类型,参数是一个EXCEPTION_POINTERS结构体指针,该结构体包含了异常发生时的上下文信息,是生成Dump必需的数据。
完整实现代码示例
下面是完整的C++实现代码,包含异常捕获和Dump写入逻辑,代码中添加了中文注释说明每个步骤的作用:
#include <windows.h>
#include <dbghelp.h>
#include <string>
// 链接DbgHelp.lib库
#pragma comment(lib, "dbghelp.lib")
// 生成Dump文件的目录,可根据实际需要修改
const std::wstring DUMP_DIR = L".\";
// 未处理异常回调函数
LONG WINAPI ExceptionFilter(EXCEPTION_POINTERS* exceptionPointers) {
// 拼接Dump文件路径和名称,使用当前时间戳避免重名
wchar_t dumpPath[MAX_PATH] = { 0 };
SYSTEMTIME systemTime;
GetLocalTime(&systemTime);
wsprintfW(dumpPath, L"%sCrash_%04d%02d%02d_%02d%02d%02d.dmp",
DUMP_DIR.c_str(),
systemTime.wYear, systemTime.wMonth, systemTime.wDay,
systemTime.wHour, systemTime.wMinute, systemTime.wSecond);
// 创建Dump文件
HANDLE dumpFile = CreateFileW(
dumpPath,
GENERIC_WRITE,
0,
NULL,
CREATE_ALWAYS,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (dumpFile != INVALID_HANDLE_VALUE) {
// 填充MiniDump相关参数
MINIDUMP_EXCEPTION_INFORMATION mdei;
mdei.ThreadId = GetCurrentThreadId();
mdei.ExceptionPointers = exceptionPointers;
mdei.ClientPointers = TRUE;
// 调用MiniDumpWriteDump生成Dump文件
MiniDumpWriteDump(
GetCurrentProcess(),
GetCurrentProcessId(),
dumpFile,
MiniDumpNormal, // Dump类型,MiniDumpNormal是普通轻量类型
exceptionPointers ? &mdei : NULL,
NULL,
NULL
);
// 关闭文件句柄
CloseHandle(dumpFile);
}
// 返回继续执行,让程序退出
return EXCEPTION_EXECUTE_HANDLER;
}
// 初始化Dump生成功能,在程序启动时调用
void InitCrashDump() {
SetUnhandledExceptionFilter(ExceptionFilter);
}
// 测试用的崩溃函数,主动触发一个访问违规异常
void TestCrash() {
int* p = nullptr;
*p = 10; // 访问空指针,触发崩溃
}
int main() {
// 程序启动时初始化Dump生成
InitCrashDump();
// 调用测试崩溃函数
TestCrash();
return 0;
}
代码说明与注意事项
- 代码中需要链接
DbgHelp.lib库,如果使用Visual Studio开发,除了#pragma comment方式,也可以在项目属性中手动添加该库的依赖。 MiniDumpWriteDump的第四个参数可以指定Dump的类型,除了MiniDumpNormal,还有MiniDumpWithFullMemory等类型,后者会记录完整内存信息,生成的文件更大,调试信息更全,可根据需求选择。- 生成的Dump文件路径默认是当前程序运行目录,如果需要自定义路径,可以修改
DUMP_DIR的值,需要确保目标目录存在,否则CreateFile会失败。 - 该程序编译后运行,会主动触发空指针访问异常,随后在指定目录生成对应的.dmp文件,使用Visual Studio或者WinDbg等调试工具打开该文件,就可以查看崩溃时的调用栈和变量信息。
常见问题排查
如果程序崩溃后没有生成Dump文件,可以先检查以下几点:
- 是否成功调用了
InitCrashDump函数,确保异常过滤器已经设置。 - 目标Dump目录是否有写入权限,避免因权限问题导致文件创建失败。
- 是否使用了调试器附加运行程序,部分调试器会优先捕获异常,导致我们设置的异常过滤器不被触发,可以脱离调试器直接运行程序测试。