WINDBG 查崩溃

Windbg教程:快速入门Windows系统崩溃分析

前言:windbg大家都很熟悉,它是做windows系统客户端测试的QA人员很应该掌握的定位程序崩溃原因的工具,

网上也有很多资料,但是真正适合QA阅读和实用的资料不多,我把我认为最重要最应该掌握的结合以前的使用经验分享一下:

基础篇

1、  打开windbg,打开dmp文件,File——〉open crash dump(其实有更方便的方法,后面会说)

2、  设置符号下载路径和加载路径,File——〉symbol file path,输入srv*d:\symbolslocal*http://msdl.microsoft.com/download/symbols,中间这个路径可以随意设置,如果有其他符号路径,比如产品的模块PDB,加分号分隔即可。

符号是可以定位到具体函数,甚至具体错在哪一行代码的。在分析过程中只要dmp中牵涉到相关的微软模块的pdb都会被下载和加载。网上也有“集合版”的pdb,可以自行搜索,但是符号对应模块的版本不一定适合。

3、  弹出一个workspace的对话框,选什么都无所谓,yes、no都一样,不需要关注

4、  打开dump以后可以看到命令行窗口,如下图打开一个IE的dump文件:

5、  上图最下方的输入窗口就是用来输入调试命令的

6、  第一条命令: !analyze –v,回车,这条命令是万金油,可以自动分析大概是谁导致的崩溃,那么它执行后要关注什么内容?看下图

7、  上图应该怎么看?从下往上看!这里面就是崩溃时内存里面的模块的执行过程。注意看“Following XXX”,字面意思是接下来的段可以错了,程序在这里崩溃了的意思,因为是从下往上走的,所以“Following XXX”上方的内容就是崩溃后的东西,而“Following XXX”下方的内容就是导致崩溃的“原因”,越接近“Following XXX”的越代表有可能是导致崩溃的直接模块,但是这不一定。如果抓到的dmp时机太迟,会出现堆栈破坏的情景,那么“Following XXX”得到的内容可能就是错误的了,那么这个dmp意义就不大,当然QA可以不关注这个,要关注的是如何让自己抓dmp的时机更及时。

8、  第二条命令:kb,回车,这条命令是上面的补充,用来显示当前线程call stack(调用栈)的内容,它可以查看更详细的内存信息,更好的定位崩溃原因,比如上图内容看不到360相关的东西,是不是说这个崩溃和360没关系呢?不一定!看kb的内容

9、  记住从下往上看!上图可以看到是IE调用了safemon.dll的函数后才开始创建dmp的,是不是有理由怀疑这个崩溃和网盾有关了?提BUG吧!

10、  可惜我们只看到和网盾有关,但是具体是网盾什么函数、什么参数导致的都看不到,如何看?这时就看出符号文件的重要性了!

Ps:还有一个命令是~*kb ,它用来显示dump中所有线程的call stack, 一般用到它说明这个dump已经比较难看了,可以从命令结果中搜索KiUserExceptionDispatcher等关键字,一般可以认为存在KiUserExceptionDispatcher的线程就是导致崩溃的线程。

高级篇 

1、  设置DMP类型文件关联用windbg打开

  a) cmd到windbg目录运行windbg –IA 

2、  手动抓DMP的方法:

  a) 如果程序崩溃后没有DMP文件生成可采取下面方法转存DUM。

  b) 当程序崩溃还没有退出的时候,开启WINDEBUGGER程序,在FILE——执行attach to a process——选择崩溃的进程。

  c) 再执行.dump /ma C:\testdump.dmp(如果没有/ma,dump大小比较小) 

3、自动抓DMP的方法:

  a) cmd到windbg目录运行 windbg -IS

  b) 进行导致崩溃的操作

  c) 即可抓到dmp,执行.dump /ma C:\testdump.dmp 

4、  使用windbg调起进程调试

  a) 开启WINDEBUGGER程序,在FILE——执行Open Executable——选择要进行调试的进程文件

  b) 当进程没有自保护或者没有反调试时,在input框输入g,回车,即可打开进程,此时如果进程发生崩溃,会被立即捕捉到。这种方法拿到的dmp比第二种更好。

5、  设置Global Flags,自动attach进程。Global Flags(简称gflags),设置它之后,目标进程启动时会立即被attach,主要用于调试一些系统进程,或“有依赖的”进程,这些进程不能直接由方法4打开,只能由其他进程调用,而调用用立即崩溃,所以也不能用方法2。这个方法同时可以设置很多检查项。

使用 WinDbg 工具找内存泄漏是一项涉及系统级调试和分析的任务,它要求对 Windows 内存管理机制和调试器命令有较深入的理解。以下是几种常用的方法和步骤,用于通过 WinDbg 检测和跟踪内存泄漏。 ### 1. 配置符号路径并附加到进程 首先,确保 WinDbg 能够访问正确的符号文件(PDB),这有助于准确地识别模块和函数。可以通过以下命令设置符号路径: ```shell .sympath SRV*C:\Symbols*https://msdl.microsoft.com/download/symbols ``` 然后,附加到目标进程: ```shell .attach <进程ID> ``` 或者,如果是从内存转储文件开始分析,则使用: ```shell .opendump <dump文件路径> ``` ### 2. 启用用户模式堆栈跟踪(UMDH) 为了更好地跟踪内存分配,可以启用用户模式堆栈跟踪(UMDH)。这需要在启动目标进程之前完成。可以使用以下命令来启用: ```shell !gflag +ust ``` 如果已经附加到进程,可以尝试重新启动进程以应用 UMDH 设置。 ### 3. 使用 `!heap` 命令分析堆内存 `!heap` 是 WinDbg 中用于分析堆内存的重要命令。它可以显示所有堆的信息,包括每个堆的大小、分配次数等。例如: ```shell !heap -s ``` 此命令会列出所有堆的摘要信息。如果发现某个堆的大小异常增长,可以进一步使用以下命令看该堆的详细信息: ```shell !heap -h <堆地址> ``` 这将显示堆的详细统计信息,包括分配块的数量和大小。 ### 4. 使用 `!dumpheap` 命令分析 .NET 托管内存 对于 .NET 应用程序,`!dumpheap` 是一个非常有用的命令,它可以列出堆中的所有对象。通过比较不同时间点的对象数量和大小,可以识别潜在的内存泄漏。例如: ```shell !dumpheap -stat ``` 此命令会按类型统计所有对象的数量和总大小。如果发现某个类型的实例数量异常增长,可以进一步使用以下命令看该类型的详细信息: ```shell !dumpheap -type <类型名称> ``` 这将列出该类型的所有实例及其地址。可以结合 `!gcroot` 命令来看这些对象的引用链,从而找到导致它们无法被垃圾回收的原因: ```shell !gcroot <对象地址> ``` ### 5. 使用 `!objsize` 命令分析特定对象的内存占用 在某些情况下,可能需要分析某个特定对象的内存占用情况。可以使用 `!objsize` 命令来获取对象的大小及其包含的字段信息。例如: ```shell !objsize <对象地址> ``` 这将显示该对象的大小及其各个字段的详细信息。结合 `!dumpobj` 命令可以看对象的具体内容: ```shell !dumpobj /d <对象地址> ``` ### 6. 使用 `!leak` 命令自动检测内存泄漏 WinDbg 提供了一个自动化检测内存泄漏的命令 `!leak`,它可以自动比较两个时间点的堆内存分配情况,识别出增长的对象类型。例如: ```shell !leak -p ``` 此命令会启动一个交互式会话,提示用户进行两次快照的对比。第一次运行时,系统会记录当前的堆内存状态;第二次运行时,系统会比较当前状态与第一次的状态,找出增长的对象类型。 ### 7. 使用 `!analyze -v` 进行全面分析 最后,可以使用 `!analyze -v` 命令进行一次全面的崩溃分析。虽然这个命令主要用于分析崩溃问题,但它也可以提供一些关于内存使用的有用信息,尤其是在分析内存不足导致的崩溃时: ```shell !analyze -v ``` ### 8. 使用 `!threadpool` 命令分析线程池 在某些情况下,内存泄漏可能是由线程池中的未释放资源引起的。可以使用 `!threadpool` 命令来看线程池的状态: ```shell !threadpool ``` 这将显示线程池的工作线程、I/O 完成端口线程等信息,帮助识别是否有线程池资源未被正确释放。 ### 9. 使用 `!clrstack` 和 `!u` 命令分析调用栈 对于 .NET 应用程序,可以使用 `!clrstack` 命令看当前线程的托管调用栈,帮助定位内存分配的具体位置: ```shell !clrstack ``` 结合 `!u` 命令可以反汇编当前的代码段,进一步分析内存分配的上下文: ```shell !u <方法地址> ``` ### 10. 使用 `!dumpmt` 和 `!dumpdomain` 命令分析类型和应用程序域 在 .NET 应用程序中,类型和应用程序域的管理也会影响内存使用。可以使用 `!dumpmt` 命令看类型元数据的信息: ```shell !dumpmt -md <方法表地址> ``` 结合 `!dumpdomain` 命令可以看应用程序域中的程序集和类型加载情况: ```shell !dumpdomain ``` 这些命令可以帮助识别是否有类型或程序集未被正确卸载,从而导致内存泄漏。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值