首页
论坛
课程
招聘
[原创]让程序崩溃时自动创建minidump
2010-2-1 21:50 23244

[原创]让程序崩溃时自动创建minidump

2010-2-1 21:50
23244
创建Minidump实际上相当的简单。主要是调用了dbghelp.dll提供的API——MiniDumpWriteDump。

函数原型是:
BOOL MiniDumpWriteDump (
HANDLE hProcess,
DWORD ProcessId,
HANDLE hFile,
MINIDUMP_TYPE DumpType,
PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
PMINIDUMP_CALLBACK_INFORMATION CallbackParam
); 

前两个参数分别是当前程序的句柄和ID,分别用GetCurrentProcess(), GetCurrentProcessId(),这两个函数就可以获得了。第三个参数是文件句柄,一般我们用CreateFile来创建一个XXX.dmp的文件,而返回的句柄就是我们所需要的。DumpType是Minidump的类型,一般来说设置为MiniDumpNormal就可以了。接下来就是最关键的一个参数ExceptionParam,这是一个指向MINIDUMP_EXCEPTION_INFORMATION 结构的指针。如果不填充这个结构那么我们的minidump就不能达到理想的效果,我会在后面谈到怎么填充这个结构。最后两个参数我认为在这里没有多大用处,我们可以简单的赋值为NULL。

接下来的问题就是,我们怎么在程序崩溃的时候自动的创建Minidump。这里我们就要用到一个Kernel32.dll提供的API——SetUnhandledExceptionFilter 。如果读过《软件调试》等书籍的朋友肯定知道,这个函数是用来设置最后的异常处理函数的。也就是当程序产生异常的时候,如果程序自身没有处理就会调用这个函数设置的异常处理函数来处理这个异常。

有了这个函数的帮助,我们就可以在程序开始的时候设置最后的异常处理函数。并在这个函数中调用MiniDumpWriteDump 。这样就可以达到理想的效果。

不过我还是觉得这个不够方便,因为我每次创建一个程序,都需要调用这个函数。能不能有一个更好的方法呢?的确是有的,我们可以写一个创建minidump的类,然后在类的构造函数中调用SetUnhandledExceptionFilter 来设置异常处理函数。最后的效果就是只需要我们加入事先写好的.h和.cpp文件,然后什么也不用做,直接编译运行就能达到理想的效果了。

再来看看我们所生成的Minidump的效果,将生产的dmp文件拖入windbg,然后!analyze -v,可以看到以下信息:

FAULTING_IP: 
test!main+28 [c:\documents and settings\administrator\XXX\test\test\test.cpp @ 6]
004115d8 c70000000000    mov     dword ptr [eax],0

EXCEPTION_RECORD: ffffffff -- (.exr 0xffffffffffffffff)
ExceptionAddress: 004115d8 (test!main+0x00000028)
   ExceptionCode: c0000005 (Access violation)
ExceptionFlags: 00000000
NumberParameters: 2
   Parameter[0]: 00000001
   Parameter[1]: 00000000
Attempt to write to address 00000000

DEFAULT_BUCKET_ID: NULL_POINTER_WRITE

PROCESS_NAME: test.exe

ERROR_CODE: (NTSTATUS) 0xc0000005 - "0x%08lx"

EXCEPTION_CODE: (NTSTATUS) 0xc0000005 - "0x%08lx"

EXCEPTION_PARAMETER1: 00000001

EXCEPTION_PARAMETER2: 00000000

WRITE_ADDRESS: 00000000 

FOLLOWUP_IP: 
test!main+28 [c:\documents and settings\administrator\×à??\test\test\test.cpp @ 6]
004115d8 c70000000000    mov     dword ptr [eax],0

FAULTING_THREAD: 00000fd4

PRIMARY_PROBLEM_CLASS: NULL_POINTER_WRITE

BUGCHECK_STR: APPLICATION_FAULT_NULL_POINTER_WRITE

LAST_CONTROL_TRANSFER: from 00413ab8 to 004115d8

STACK_TEXT: 
0012ff68 00413ab8 00000001 003929d0 00393138 test!main+0x28 [c:\documents and settings\administrator\×à??\test\test\test.cpp @ 6]
0012ffb8 004138ff 0012fff0 7c817077 80000001 test!__tmainCRTStartup+0x1a8 [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 582]
0012ffc0 7c817077 80000001 04a3d9e4 7ffd5000 test!mainCRTStartup+0xf [f:\dd\vctools\crt_bld\self_x86\crt\src\crtexe.c @ 399]
0012fff0 00000000 004111bd 00000000 00000000 kernel32!BaseProcessStart+0x23


STACK_COMMAND: ~0s; .ecxr ; kb

FAULTING_SOURCE_CODE: 
     2: 
     3: void main()
     4: {
     5: int *p = 0;
>    6: *p = 0;
     7: }


SYMBOL_STACK_INDEX: 0

SYMBOL_NAME: test!main+28

FOLLOWUP_NAME: MachineOwner

MODULE_NAME: test

IMAGE_NAME: test.exe

DEBUG_FLR_IMAGE_TIMESTAMP: 4b66ae0d

FAILURE_BUCKET_ID: NULL_POINTER_WRITE_c0000005_test.exe!main

BUCKET_ID: APPLICATION_FAULT_NULL_POINTER_WRITE_test!main+28

WATSON_STAGEONE_URL: http://watson.microsoft.com/StageOne/test_exe/0_0_0_0/4b66ae0d/test_exe/0_0_0_0/4b66ae0d/c0000005/000115d8.htm?Retriage=1

Followup: MachineOwner
---------



最后附上这个类的代码,至于用法非常简单,只需要把类的两个文件加入你的工程中就行了。

[2023春季班]《安卓高级研修班(网课)》月薪两万班招生中~

上传的附件:
收藏
点赞1
打赏
分享
最新回复 (18)
雪    币: 285
活跃值: 活跃值 (34)
能力值: ( LV7,RANK:100 )
在线值:
发帖
回帖
粉丝
飞心男孩 活跃值 2 2010-2-3 15:15
2
0
虽然没有测试,但既然下载了就顶~!
雪    币: 203
活跃值: 活跃值 (32)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lx6636 活跃值 2010-2-5 09:08
3
0
不错,很有价值

方便了我们程序员的调试工作

不过...MFC类库不是也有Dump操作么。唔,不用MFC库的话,是很有用的
雪    币: 224
活跃值: 活跃值 (111)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
qiluword 活跃值 2010-2-5 11:03
4
0
不错,方便调试
雪    币: 7510
活跃值: 活跃值 (412)
能力值: ( LV9,RANK:610 )
在线值:
发帖
回帖
粉丝
achillis 活跃值 15 2010-2-5 12:08
5
0
以前我一个程序偶尔会崩溃但找不到原因,又不好重现,用这个看看有没有帮助。。
雪    币: 5196
活跃值: 活跃值 (1050)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
sisess 活跃值 1 2010-2-14 12:29
6
0
这个太谢谢了 找BUG方便了很多
雪    币: 708
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
MiSHE 活跃值 2010-2-14 12:35
7
0
学习,感谢分享
雪    币: 326
活跃值: 活跃值 (15)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
快雪时晴 活跃值 4 2010-2-14 13:07
8
0
一直未接触过dump,今入门

其他语言的怎么利用呢
雪    币: 224
活跃值: 活跃值 (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
vvsky 活跃值 2010-2-15 00:52
9
0
错误报告 包括dump
推荐下 BugTrap
http://bleepsoft.com/bugtrap/
http://www.codeproject.com/KB/applications/BugTrap.aspx

另外svn源码里的crashrpt1.0也不错,目前在google code上有2.0版本
雪    币: 1407
活跃值: 活跃值 (17)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
liangdong 活跃值 2010-2-15 13:24
10
0
支持楼主
收藏下ls提供的链接
雪    币: 507
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
BeWideWay 活跃值 2010-2-23 15:55
11
0
不错  对BUG定位很有帮助。
雪    币: 201
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
梦之铃 活跃值 2010-3-24 01:42
12
0
这东西在Delphi如何使用?
雪    币: 161
活跃值: 活跃值 (15)
能力值: ( LV10,RANK:170 )
在线值:
发帖
回帖
粉丝
thinkSJ 活跃值 4 2010-3-25 10:17
13
0
下载了,多谢LZ
雪    币: 185
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
第七城市 活跃值 2010-12-17 00:21
14
0
下载就要支持下。
雪    币: 564
活跃值: 活跃值 (23)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
lixupeng 活跃值 2010-12-17 08:43
15
0
也能用
雪    币: 232
活跃值: 活跃值 (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
dlmu 活跃值 1 2010-12-17 08:50
16
0
很好用呀!
雪    币: 84
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
xnop 活跃值 2011-4-15 01:44
17
0
挺不错的
雪    币: 23
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
小P孩儿 活跃值 2011-4-15 08:00
18
0
不错嘛…太有用了!
雪    币: 68
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
sunnywwc 活跃值 2011-4-15 11:16
19
0
不错 顶 前几天 搞了半天SetUnHandleExceptionFilter这个函数
游客
登录 | 注册 方可回帖
返回