文章1:
Debugdiag可以用来追踪windows下程序崩溃,卡死(包括死锁),断言等一些疑难问题的原因,对检测程序内存泄漏也有很好的帮助,相对于另外一款windbg调试器来说,是程序员的轻量级武器。
本文讲述debug版本(release版本也可以,只不过debug版本能更明显地定位引起出错的代码行)的程序在程序崩溃,卡死,和出现断言时,怎样用debugdiag来帮助定位源代码中引起问题的代码。
一 程序崩溃时,debugdiag抓dump文件的方法
注意在程序崩溃之前,就要用debugdiag设置好rule,打开Tools/Rule Actions/Add Rule…对话框,选择Crash,单击下一步,选择A specific process,这里以程序test_crash.exe作为例子,输入test_crash.exe,如下图所示:
单击下一步,根据需要选择相应的选项,这里选择Log Stack Trace,表示记录崩溃时的堆栈情形。如下图所示。
接下来一路单击下一步,然后单击完成激活这个rule,运行test_crash,按回车,程序崩溃,会在Rules选项卡界面显示Userdump计数和Userdump路径,打开dump文件所在文件夹,右击生成的dump文件,选择Analyze Crash/Hang Issue,会生成一个分析报告,这里贴出其中二段。
In test_crash__PID__1912__Date__06_07_2011__Time_01_18_08PM__840__Second_Chance_Exception_C0000094.dmp the assembly instruction at test_crash!main+3f in E:\practice\test\Debug\test_crash.exehas caused an unknown exception (0xc0000094) on thread 0
Thread 0 – System ID 5584
Entry pointtest_crash!ILT+280(_mainCRTStartup)Create time2011-6-7 13:18:00Time spent in user mode0 Days 0:0:0.0Time spent in kernel mode0 Days 0:0:0.15FunctionArg 1Arg 2Arg 3Sourcetest_crash!main+3f00000001003f56c0003f3220 test_crash!__tmainCRTStartup+1a60012fff07c8170777c930981 test_crash!mainCRTStartup+d7c930981000a06087ffdc000 kernel32!BaseProcessStart+230041111d0000000078746341
注意到test_crash!main+3f这里,就是造成崩溃的具体代码行地址(基于汇编指令来说),意思就是说, 造成崩溃的具体代码行地址 = main函数地址+偏移0×3f。可以对源程序反汇编验证一下,可以看到是004113FF idiv eax,dword ptr [i]这一行导致的崩溃,而0×004113C0加上0×3F正好等于0×004113FF,反应到实际代码上就是语句
int k = j / i;
导致的崩溃。
注:test_crash的C++源码附于文章末尾。
004113C0 push ebp
004113C1 mov ebp,esp
004113C3 sub esp,0E4h
004113C9 push ebx
004113CA push esi
004113CB push edi
004113CC lea edi,[ebp-0E4h]
004113D2 mov ecx,39h
004113D7 mov eax,0CCCCCCCCh
004113DC rep stos dword ptr es:[edi]
004113DE mov dword ptr [i],0
004113E5 mov dword ptr [j],1
004113EC mov esi,esp
004113EE call dword ptr [__imp__getchar (418340h)]
004113F4 cmp esi,esp
004113F6 call @ILT+325(__RTC_CheckEsp) (41114Ah)
004113FB mov eax,dword ptr [j]
004113FE cdq
004113FF idiv eax,dword ptr [i]
00411402 mov dword ptr [k],eax
00411405 mov esi,esp
00411407 mov eax,dword ptr [__imp_std::endl (418298h)]
0041140C push eax
0041140D mov edi,esp
0041140F mov ecx,dword ptr [k]
00411412 push ecx
00411413 mov ecx,dword ptr [__imp_std::cout (418290h)]
00411419 call dword ptr [__imp_std::basic_ostream
0041141F cmp edi,esp
00411421 call @ILT+325(__RTC_CheckEsp) (41114Ah)
00411426 mov ecx,eax
00411428 call dword ptr [__imp_std::basic_ostream
0041142E cmp esi,esp
00411430 call @ILT+325(__RTC_CheckEsp) (41114Ah)
00411435 xor eax,eax
注:
只有在满足如下条件时,才能根据dump文件定位是哪个函数中哪一行出了问题。
一. 生成了程序的PDB文件
二. 程序和PDB文件完全匹配
三. 程序的dump文件和PDB文件同时存在,并且PDB文件所在目录为原来生成程序的目录
否则只会给出从基址(一般是0×00400000)开始的偏移量(其实这样就已经能定位问题,只不过还需多做几步),不会给出具体的函数信息。
二 程序卡死或者断言,debugdiag抓dump文件的方法
程序卡死或者出现断言时,靠debugdiag的自动抓dump文件rule还不一定能奏效,但是这种情况下程序没有退出,现场还保留着,这时可以直接导出dump文件来跟踪问题。这里以程序test_assert作为例子,程序虽然简单,但是通过这种方法就能够定位所有断言问题。运行test_assert出现断言,如下图所示:
在debugdiag的Processes选项卡中找到test_assert进程,然后右击,选择Create Full Userdump或者Create Mini Userdump,然后会提示dump文件在哪个目录,选择是,到dump文件所在目录,一般在debugdiag安装目录的Logs\Misc目录下,右击刚才生成的dump,选择Analyze Crash/Hang Issue,同样也会生成分析报告,同程序崩溃时的分析报告类似,也会指出具体断言原因,这里就不再赘述了。
附test_crash源码:
#include
int main()
{
int i = 0;
int j = 1;
getchar();
int k = j / i;
std::cout << k << std::endl;
return 0;
}
原文地址:
http://hi.baidu.com/roger_long/item/2373c620e7c8188d6f2cc3c2
文章2:
手动抓取IIS dump文件
1、启动DebugDiag 1.1 (x86)后点击“选择规则类型”窗口中的“取消”按钮后,点击Processes分页。
2、右键单击w3wp进程,并选择Create Full Userdump
等待一段时间后出现成功创建dump文件,以及dump的文件名和存储路径的对话框,点击确定即可。
查看dump文件的默认存储位置
1、点击DebugDiag 1.1 (x86)工具主窗口工具栏中的“文件夹”图标
查看弹出的窗口
打开其中的misc文件夹,刚才所抓取的dump文件就存放在其中。
修改dump文件的存储位置
点击DebugDiag 1.1 (x86)工具菜单栏中的“Tools”->“Options and Settings”设置Manual Userdump Save Folder中的路径为所要修改的路径即可。
抓取dump文件的时机
1、应用程序初始化完毕(测试执行前)需要抓取一个dump文件
2、使用性能计数器观察测试中的内存使用情况,在IIS崩溃前(观察Prvite和#time in GC的变化)抓取dump文件以便于开发分析
3、(可选)在性能计数器中观察gen2、large object heap、bytes in all heaps堆的使用和释放情况,在堆的使用即将达到一个高峰值(相对值)前抓取dump,并同时抓取堆释放到一个低峰值(波谷)前抓取一个dump,方便开发对比分析。
原文地址:http://www.51testing.com/html/76/227476-99975.html