一、基本介绍
Windows平台提供了一个API函数名为minidumpwritedump,是一个非常有用的函数。
它可以帮助我们生成一个dump文件,这个文件能够记录下程序崩溃时的一些关键信息,例如call stack,CPU的寄存器状态等等,这个文件对于解决问题非常有帮助。
下面我们就来详细说明一下这个函数的使用方法。
二、函数参数
下面是函数的定义:
BOOL WINAPI MiniDumpWriteDump( HANDLE hProcess, DWORD ProcessId, HANDLE hFile, MINIDUMP_TYPE DumpType, PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, PMINIDUMP_CALLBACK_INFORMATION CallbackParam );
我们来逐一介绍这些参数:
1、hProcess
这个参数代表着Dump的进程句柄,一般这个参数填NULL,表示当前进程。
2、ProcessId
如果hProcess是NULL,那么这个参数用来指定进程的ID,注意这个进程必须与当前进程在同一Session。
3、hFile
代表着Dump文件的句柄,可以把Dump文件写入磁盘或任何支持写入的非易失性存储设备中。如果想直接打印到控制台,可以填入代表标准输出的handle。
4、DumpType
这个参数指定生成Dump文件的类型,具体类型如下:
- MiniDumpNormal: 生成最基本的dump文件,不包含Secondary Memory.
- MiniDumpWithDataSegs: 同样也仅包含主模块、Call Stack和寄存器状态,同时也有Secondary Memory的一部分(Data Sections),但是不包含堆的全量数据。
- MiniDumpWithFullMemory: 全量dump,包含了进程地址空间中的所有部分,要求调用进程需要以管理员身份运行。
- MiniDumpWithHandleData: 包含所有句柄对象的详细信息,比较适合用来分析句柄泄露。
- MiniDumpWithUnloadedModules: 可以包含主模块、附加模块和卸载的模块的明细信息。
5、ExceptionParam
这个参数是一个PMINIDUMP_EXCEPTION_INFORMATION类型指针,简单说法它提供了一个指针,指向了一个可选的MINIDUMP_EXCEPTION_INFORMATION结构,其中包含了一个指向当前异常的指针,不能为NULL。
6、UserStreamParam
这个参数是一个PMINIDUMP_USER_STREAM_INFORMATION类型指针,支持往Dump文件添加自定义Stream。这个参数也可以为NULL,表示不给Dump文件添加用户Stream。
7、CallbackParam
这个参数是一个PMINIDUMP_CALLBACK_INFORMATION类型指针,支持在生成Dump文件时传入一个回调函数指针,在dump文件生成过程中可以定制一些行为,这个参数也可以为NULL,表示不需要回调函数。
三、使用示例
#include "windows.h" #include "DbgHelp.h" #pragma comment(lib, "Dbghelp.lib") int Foo(int x) { char* p; *p = 0; return x; } int main(int argc, char* argv[]) { LONG retVal = EXCEPTION_EXECUTE_HANDLER; __try { Foo(1); } __except(MiniDumpWriteDump(GetCurrentProcess(), GetCurrentProcessId(), CreateFile("D:/dump.dmp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL), MiniDumpWithFullMemory, NULL, NULL, NULL)) { retVal = EXCEPTION_CONTINUE_SEARCH; } return retVal; }
上述代码会在main函数中调用Foo函数,而Foo函数会发生exception,然后__except中的代码会被执行,这个时候我们就可以在__except的代码中调用MiniDumpWriteDump。我们调用这个函数时,传入GetCurrentProcess()和GetCurrentProcessId()即可。
如果__except捕捉到了Exception,函数返回的值为EXCEPTION_CONTINUE_SEARCH,否则返回EXCEPTION_EXECUTE_HANDLER。
四、注意事项
Dump文件大小会随进程的大小而增长,并且可以阻止代码执行,因此应该小心地使用。
在开发过程中只需要生成一个最小的Dump文件,然后追踪进一步的信息即可。
生成Dump文件的性能较差,因此不应该在高频率的代码路径中使用它。