使用ProcDump工具抓取dump
首先得到要抓取的进程号
cd %windir%\syswow64\inetsrv
appcmd list wp
得到pid之后,
在任务管理器里发现w3wp.exe的CPU总在49%-60%左右, 间歇性地会下降一些. 我们需要在w3wp.exe的CPU在50%以上并能维持三秒钟的情形下抓取两组dump. 如果使用debug diag或adplus的话, 会比较困难, 因为这需要等待时机并手动抓取. 容易出现抓到的dump里不包含那些引发异常的动作的情况.
解决方案 - 救世主procdump
===============
Procdump可以很方便地帮助我们应付这种情况, 加速动作过程, 抓取正确数据集合. 它会指定的时间内监控目标进程的cpu, 并在那个点抓取一个内存快照(dump).
比如说:
procdump -ma -c 50 -s 3 -n 2 5844(Process Name or PID)
-ma 生成full dump, 即包括进程的所有内存. 默认的dump格式包括线程和句柄信息.-c 在CPU使用率到达这个阀值的时候, 生成dump文件.
-s CPU阀值必须持续多少秒才抓取dump文件.
-n 在该工具退出之前要抓取多少个dump文件.
WinDBG不是专门用于调试.Net程序的工具,它更偏向于底层,可用于内核和驱动调试。进行普通的.Net程序调试还是使用微软专为.Net开发的调试工具MDBG更方便一些。但是WinDBG能看到更多的底层信息,对于某些特别疑难的问题调试有所帮助,例如内存泄漏等问题。
工具下载: WinBdgTool.zip
测试代码下载 : MyDumpTest.7z
首先添加设定符号文件路径(Symbol Path),当你使用Visual Studio编译程序时,是否有留意到在bin/Debug文件夹下会有.pdb后缀的文件?这些文件包含有dll程序集的调试符号,pdb文件并不包含有执行代码,只是使调试工具能把代码执行指令翻译为正确的可识别字符。微软提供了包含大量pdb文件的公共服务器,地址如下:http://msdl.microsoft.com/download/symbols。打开windbg程序,选择“File->Symbol File Path…“,把下面的内容复制进去保存。srv*c:\temp*http://msdl.microsoft.com/download/symbols。
下面这行命令 如果你发现出现Unable to verify checksum...或者的消息 那是因为你没有添加.net的sos扩展或者sos的版本没有对应上。.Net1.1时代的SOS扩展已经自带于下载安装的WinDBG中,从.Net2.0以后,SOS扩展已经自带到.Net框架中:C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\SOS.dll,为了不至于引起混淆,最好的方法就是使用前面的loadby调试器元命令来让WinDBG自己决定加载什么版本的SOS。
添加sos:.load C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\sos.dll。
加载SOS后,使用命令.chain来查看调试链中是否已经成功包含SOS扩展。
通过!eeversion查看sos的版本号。
实战命令: ~ 查看线程
这表明当前dump里记录的线程数。如果要切换线程,用波浪线+序号+s来切换,如切换到线程2,那么用~2s即可。
lm 查看你加载的模块
kb 查看native code调用栈
用~现在只有线程信息,对于每个线程,在被抓的那一刻,在执行什么,我们有命令:kb。
看到clr大家应该很眼熟吧。这里已经可以看到较详细的调试信息了。
!runaway (查看线程对应 CPU 运行时间)
因为我们的测试程序是测试的是线程阻塞所以我们选一个运行时间为0的,例如415
!dso 查看这个堆栈中的对象
!clrstack 查看这个线程的托管代码调用栈
通过上面我们已经可以看出这个线程一直都是处于阻塞状态。
到这里基本上一个小的测试程序可以告一段落了,当然windbg的功能远远不止如此,这里分享一些资源给大家。
资源下载 : WinDbg入门.rar Windbg用法详解.7z
三. dump的自动分析
1. debugdiag
这里有几种规则类型的选择,一般我们常用的用crash来查看锁和堵塞的情况,performance来检查性能的问题。
选择完成后直接点击开始分析
生成报表
查看描述
点击详细
这样,红色字体就是问题的所在。然后根据具体问题下发到对应开发部门解决。
2. Hang自动化分析
在WinDbg输入如下命令
.shell -ci "~* kb;.echo MANAGED THREADS;!threads;.echo MANAGED CALLSTACKS;~* e !clrstack;" D:\xx.exe