前面一篇写过《Windbg调试----Windbg入门》,可能不少新手会问,我在本地用Visual Studio去做调试就行了,为什么还需要那么抽象的Windbg去进行调试呢?
那是因为: 客户环境复杂多样, 发布的软件,经常会出现在本地测试无法重现的问题。我们不可能在客户的环境装一个几十G的Visual Studio,那么一般会先通过Debug Log进行初步的分析,但是碰到程序崩溃,程序死锁,内存泄漏等,只利用Debug log去做分析是非常困难的。这个时候需要借助程序dump来做进一步的分析,进程的dump主要就是指当前运行进程的状态保存到一个文件,主要包含有进程相关的信息,比如当前函数调用栈,堆,线程运行时间等。本文主要描述了几种收集dump的工具和一些使用场景。
WIndows任务管理器生成Dump
这个方法比较简单,当你发现程序比如出现了Memory Leak或者死锁的时候,需要直接生成Dump。如下图打开Windows任务管理器
,右键需要产生dump的进程,选择创建转存文件
。
adplus收集Dump
adplus是windows 调试工具集中的一个工具,安装了WDK或者Windbg后在安装目录都有。现在很多的OS 都是64位了,但有时候Crash的程序是32位,有时候Crash的程序是64位,这里建议,如果是32位的程序 采用32位的adplus,64位的程序采用64位的adplus。
获取Crash情况下的Dump
采用如下命令:
ADPlus.exe -crash -FullOnFirst -po test.exe -o c:dumps
上面命令表示,获取test.exe
crash时Full的First Chance和Second Chance的dump,并且存放到C:dumps
目录(记得提前创建这个目录)。如果有多个进程叫test.exe,则最好使用-p <进程ID>
直接指定需要获取dump的唯一进程。
获取程序未响应时候的Dump
采用如下命令:
ADPlus.exe -hang -po test.exe -o c:dumps
本人测试了下也可以在程序正常运行的时候,直接用这个命令获取Dump。这样可以分析dump,查看程序运行时的状态,比如查看死锁问题。
使用procdump
很多时候安装adplus需要安装windbg或者WDK不是很方便,也可以直接使用procdump这个工具。在微软Sysinternals可以下载。
procdump.exe -ma test.exe -t -e -o C:dumps
当然也可以指示进程的ID去获取dump。有一种场景,当进程启动过程中或者启动一会儿就Crash,那么用Adplus就不适合,因为Adplus得进程启动后才能使用,那么可以用procdump如下命令, 等待test.exe启动,然后抓取dump。
procdump.exe -ma -w test.exe -t -e -o C:dumps
使用Windbg产生Dump
这是博主最喜欢的方式,因为windbg基本可以抓到所有场景下的dump:运行时,crash时候,hang等等。。。
Windbg JIT调试产生Dump
JIT (Just in Time)调试,一般指及时调试。如果设置了Windbg作为JIT调试器,则程序出现crash的情况,将自动弹出windbg attach到程序的异常位置。使用提升后的管理员权限,运行如下命令:
windbg -IS
实际上windbg的这个命令就是设置了windows的注册表项,在HKEY_LOCAL_MACHINESOFTWAREWow6432NodeMicrosoftWindows NTCurrentVersionAeDebug
注册表下。
如果想关闭掉Windbg作为JIT调试器,可以通过删除注册表HKEY_LOCAL_MACHINESOFTWAREWow6432NodeMicrosoftWindows NTCurrentVersionAeDebugDebugger
当程序Crash的时候,会自动弹出windbg,并且自动attach到程序,可以直接在windbg窗口中输入以下命令获取full dump:
.dump /ma D:test.dmp
程序运行时产生Dump
直接用windbg attach到需要产生Dump的进程,然后运行如下命令:
.dump /ma D:test.dmp
Crash的时候直接产生Dump
这种方法结合了上面的方法,有以下个优点: 不用指定程序,只要系统有程序Crash就产生Dump。利用了Windbg安装包中的ntsd(cdb也同样可以)。方法如下:
- 添加或者修改注册表
HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionAeDebug
下的Debugger
(REG_SZ类型):"<ntsd绝对路径>" -noio -p %ld -e %ld -g -c ".dump /ma /u D:dumpsdump.dmp; q"
。表示当有程序crash的时候利用ntsd产生dump到路径D:dumps
,dump的文件名中包含有时间和进程名字,避免了不同进程dump的文件覆盖问题。 - 添加或者修改注册表
HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionAeDebug
下的Auto
(REG_SZ类型):1
。