WinDBG调试技巧LeoJiangJiangFengbing@gmail.com什么是WinDBGDebuggingToolsforWindows简称为WinDBG根据CPU指令架构的不同分为:x86版下载6.8.4.0AMD64版下载6.8.4.0IA64版下载6.8.4.0WinDBG可以调试什么?调试应用程序调试驱动分析dumpWinDBGVSVC自带调试器WinDBG利用自带的符号检查下载工具,可以获包含VC自带的符号文件外,系统大部分DLL或EXE的符号文件,调试粒度更小。而VC除了自带的符号文件,和自身产生的符号文件外,只能使用DLL导出的函数作为符号。WinDBG可以调试驱动;VC不能,只能作为普通的应用程序调试器WinDBG和VC都支持远程调试WinDBG和VC调试器的关系相同的核心dbghelp.dll+dbgeng.dll不同的IDE只是VC没有把核心所有的功能都开放出来WinDBG加载符号File-SymbolFilePath;或者Ctrl+S;或者命令行两种符号格式srv*\\jiangfengbing\symbols$*表示从\\jiangfengbing\symbols$这个可写共享去加载pdb,如果pdb不存在则从这个地方下载,加到\\jiangfengbing\symbols$,同时加载进调试器;表示;后面还有一个符号信息D:\work\code\kis\trunk\product\win32d表示要加载D:\work\code\kis\trunk\product\win32d目录里面的pdb文件让VC获得同样的符号加载功能把WinDBG安装目录下的symsrv.dll拷贝到VC的IDE目录,类似于D:\DevTools\MicrosoftVisualStudio8\Common7\IDE\,VC2005默认是有这个文件的,但版本已老启动VC,打开Tools-Options中设置(每个版本的VC设置有所不同)用WinDBG保存dump发现程序运行异常,又不能立刻确定原因,又怕调试后找不到原因,且现象不能重现。这个时候需要保存现场。打开WinDBG,按F6attach到目标进程,然后.dump/maC:\dump\xxx.dmp不要直接退出WinDBG,先detach在退出WinDBG,否则目标进程会被关闭对测试来说,这个功能很有效。dump不是崩溃的时候才能产生,而是随时可以产生,只要你会用WinDBG使用WinDBG分析dumpKIS2008在编译的时候都保存了pdb文件,而且加入了异常模块生产dump,所以分析dump变成了程序员的基本要求没有技巧,只有流程加载崩溃程序的pdb(要版本相符),加载系统模块的pdb,符号越全越好;符号不全,可能导致你看到的stack是错误的如何看加载了哪些symbol,使用命令lm,WinDBG会把该进程的module都显示出来,如果有symbol,后面会显示symbols字样对于应用崩溃(包括应用程序和驱动)产生的dump,在加载完符号后,可以让WinDBG自动分析分析,执行命令!analyze-v即可。对于手工尝试的dump,一般currentthread不是出问题的thread,所以要看所有的线程,执行命令~*kb,显示所以的线程的callstack。大部分问题,只要看一眼就出来了。设置好源代码的路径,甚至可以找到出问题的一行。其他所要使用到的技巧后面再详细阐述。注意用户通过键盘触发的minidump是没有分析意义的。调试,分析就是找联系;符号,代码,等都是联系的桥梁,如果没pdb,怎么办?那image(目标dll或者exe)就是你的主要桥梁了,IDA将是你手中的另一个利器。主动调试应用程序打开WinDbg,Ctrl+E,打开想要调试的EXE打开WinDBG,F6,attach到要调试的进程*设置symbol加载路径,设置源代码目录,使用WinDBG就和VC一样,包括快捷键*优点:如果你在测试的机器上调试问题,装VC根本不现实,而安装WinDBG则很容易,体积小,你只要把你开发机器上的符号,源代码共享,就可以利用这个体积轻量级的工具实现功能非轻量级的调试了。被动调试一般用来调试服务。因为我们没法由我们的调试器去加载服务进程。服务进程只能由service.exe去创建。因此我们希望目标一启动,我们的调试器就attach上去了。WinDBG自动的工具GlobalFlags可以帮我们的忙当然也可以使用VC的即时调试器大部分服务是不和桌面交互的,所以在WinXP下面,你还需要把服务设为和桌面交互的,否则WinDBG运行在一个你看不见的桌面,而你又过不去那个桌面。scconfigkistype=owntype=interact然后启动服务,你就看见WinDBG出来了请快速的让进程走过RegisterServiceCtrlHandlerEx这个函数。否则超时后,进程和WinDBG都会被结束,不再有调试机会。被动VS主动调试是大胆假设,小心求证的过程断点,watch只要能达到目的就是好方法。MessageBoxVS__asmint3MessageBox让程序运行到指定的地方,等待主动进入的调试__asmint3让程序运行到指定的地方,直接触发进入即时调试器把WinDBG作即时调试器用想要崩溃的时候就由WinDBG调试执行windbg.exe-I辅助ApplictionVerifier不是WinDBG的特有功能,VC的调试器也可以配合AppVerifier原理:AppVerifier替换了一些关键API,并在这些API上作检查验证,并以调试信息输出和产生int3中断的形式告诉外面的调试器用来发现一般调试发现不了的问题,和模拟低资源的情况进阶技巧(命令篇).exr显示异常记录!handle显示一个handle的信息.thread切换currentthread!locks检查有无死锁u反汇编指定地址ddbdd显示指定地址的内存bpbcbd下断点清断点禁断点ba下内存断点进阶技巧(内核调试)联机内核调试是NT系统自带的一个功能,使用softice可以作单机的内核调试,但缺点太多,不再流行掌握了双机连接的流程,调试驱动就像调试应用程序一样。双机联调其他方式1394卡,很方便,但需要host和target机都有1394卡,虚拟机不能模拟USB,XP很麻烦,需要特殊的cable,好像用VMWare可以调试Vista系统进阶技巧(实战)一个真实案例的微缩版本update.exe,kavstart.exe,kwatch.exe你看到的现象是update.exe卡死,而真正的原因是kwatch.exe里面出了问题进阶技巧(二次开发)利用WinDBG的二次开发接口进行开发利用dbghelp.dll(+dbgeng.dll)进行定制功能的调试器开发,如:dump自动分析器如果是完全安装WinDBG的,在WinDBG安装目录,将有一个sdk目录,里面有二次开发的头文件,lib文件,sample和详细的帮助驱动开发注意问题Nonpaged和PagedPool,Nonpaged资源有限,但Nonpaged可以在各个IRQL上访问注意CPU切换,即KeWaitForXXX,KeSetEvent等的操作(例如:IRQL=DISPATCH_LEVEL时KeSetEvent第三个参数必须为FALSE,某些时候不允许CPU切换)IRQL过低时KeRaiseIrql,操作完再KeLowerIrqlIRQL过高时,自己创建SystemThread去做,或者IoQueueWorkItem把任务插都system的队列里面去做善于利用BugCheck信息驱动的VerifierDriverVerifierWHQL测试针对平台+驱动+功能的一个比较完备的测试功能完整性驱动稳定性通过测试才可以获得驱动的数字签名订阅WHQL周报hicwhql9@microsoft.com其他工具DeviceTreeWinobjIrpMonDbgView(orDbgMon)EndQuestion&AnswerThanks!