调试Bug的神兵利器:通过WinDbg条件断点收集Log [转载]

转载链接:http://blog.csdn.net/atfield/article/details/4037248

前段时间花了几天一直在用WinDbg调试一个比较棘手的Bug。这个Bug是C#
Team那边发现的,他们的Testcase跑大概10分钟左右会出一个在CLR内部的ASSERT。比较难调试的主要原因在于ASSERT表明一个全局的数据结构出现了问题,本来不应该用完的数组却已经用完了(因为按照设计,这个数组是边使用边清理的,是不会用完的)。初步想到的有下面几种方案来调试:

1. 设置数据断点

2. 一步一步调试

3. 添加Log代码

设置数据断点的主要问题是不太好确定到底是因为什么原因导致的数据结构问题,而且因为是数组被用完,很难将是到底是哪一个数组元素的加入导致了数组被全部占用,因此无法通过设置数据断点的方法来调试。一步一步的调试显然也没法解决问题,因为这个Testcase本身要跑十分钟,可以想象单步调试运行十分钟的程序会花费多长时间。因此两个方案都被我否决。添加Log代码其实是可以的,只是需要修改代码,每次修改之后需要重新编译代码,然后需要在目标机器上安装,而且C#使用的CLR的Branch并非我们正在开发的Branch,需要重新下载源代码,相对比较麻烦。最后为了解决这个问题,我采取的方法是使用WinDbg的条件断点+Log的方式。大致的方法如下:

第一步:在一个或者多个可疑处设置断点

bu[ID] [Options] [Address [Passes]] ["CommandString"]

bu是WinDbg中的设置Unresolved
Breakpoints命令,用起来比较方便,我比较喜欢用。address就是你所要断的代码地址,可以是函数开始,也可以是某一行。Command非常重要,它表示了WinDbg在每次断到address的时候都要执行的命令,不同命令用分号隔开,如:

.echo [Function A]; dv this; kb; g

这几条命令意思是:打印[Function
A],打印this指针的值,打印当前调用栈,然后继续执行。大家可以根据实际情况添加一些其他命令打印一些自己所需要的信息。通过上面这套命令打印的内容大致如下:

[FunctionA]

this = 0xABCDEFG

module!FuncA

module!FuncB

module!FuncC

可以看出,这条断点如果反复被断,那么在WinDbg的命令窗口中便会把每次断点被Hit的相关信息通过刚才定义的命令打印出来。如果定义了很多这样的断点,那么在命令窗口中就会把整个程序执行的情况打印出来,起到Log的作用,而且可以显示调用栈等信息,比一般的Log要强大许多。

第二步:设置Log

缺省情况下,WinDbg的Buffer大小是有限的,如果程序运行时间比较长,那么Buffer可能会不够,我们通过条件断点打出的信息会被截断。幸好,WinDbg提供了将命令窗口的内容输出到Log中的功能。选择Edit->Open/Close
Log File菜单项,WinDbg会显示如下对话框:

在这个对话框里面输入你想要保存的Log文件名即可。如果是添加新的内容而不是覆盖原有的,则勾上Append。

第三步:分析Log

当获得了Log信息之后,下一步就需要分析Log的内容了,这是一件需要耐心、对数据的敏感、以及一点点运气的事情。分析的时候可能发现Log的信息不足,这时就需要添加新的断点或者修改打印的信息,重新收集Log,再加以分析,直到Log信息足够为止。这时WinDbg设置条件断点的优势就出来了,因为不需要修改代码,编译代码,部署代码这样的一个过程,而是只需要键入不同的命令而已。经过几次调整断点位置和打印的信息并重新收集Log,我最终通过分析发现这个Bug是只有可能在特定情况下RCW没有被GC,并且创建线程退出的时候才会出现,具体的内容因为涉及到.NET
4.0中还没有发布的新功能,这里就不多说了。可以看到,如果采用常规的方法,对于这种在特定的条件下才会重现的问题是很难发现的。

总之,使用WinDbg来设置条件断点,打印相关信息,并且输出到Log文件是一种非常强大的调试方法,可以调试一些非常复杂的Bug,而且具有不需要修改代码的灵活性,可以自由定义自己想需要打印的信息和断点设置的位置,主要的缺点是方法稍显复杂,不过如果适应了之后还是很方便的。我强烈推荐大家在遇到比较复杂的Bug的时候,可以尝试使用一下这种方法,可能具有意想不到的效果哦。

调试Bug的神兵利器:通过WinDbg条件断点收集Log [转载],布布扣,bubuko.com

时间: 2025-01-17 07:55:57

调试Bug的神兵利器:通过WinDbg条件断点收集Log [转载]的相关文章

Eclipse调试Bug的七种常用技巧(转)

摘要:本篇文章主要介绍了Eclipse在调试代码时用到的几种调试方法,并附于截图方便理解. 本文写给那些像几年前的我一样刚刚走出校门,及一些未使用过这些高级些的调试技巧的人. 记得刚刚毕业的时候,自己连断点也不会打,当时还在用JCreate ,就连毕业设计也是用 System.out 找 Bug 的,想想真的很笨.开始工作后,一个星期过去了,在一个 1 . 2 百万行的系统中找 Bug ,我依然在用 System.out ,当时最痛苦的就是修改代码,每次找到疑似 Bug ,就输出一下,然后重启(

[软件测试_hw1]记一次调试bug的经历

上学期期末web开发的大作业,要求写一个通缉犯管理系统,基本要实现的功能归结起来不外乎数据库的增删改查.大体实现起来很容易,但在一些细节上让我纠结了很久.其中一个就是中文乱码的问题.其中主要涉及一下两个方面: 一.无法在mysql数据库中插入中文的数据,一旦涉及中文数据,在数据库中就会变成乱码.经过查询发现是由于数据库的默认编码设置的问题,将相应表和列的编码设置成UTF-8即可 二.页面显示乱码. 1.通过<%@ page language="java" import="

WinDbg配置与下载 (转载)

WinDbg配置和使用基础 WinDbg是微软发布的一款相当优秀的源码级(source-level)调试工具,可以用于Kernel模式调试和用户模式调试,还可以调试Dump文件. 1. WinDbg介绍:Debugging Tools and Symbols: Getting Startedhttp://www.microsoft.com/whdc/devtools/debugging/debugstart.mspxA word for WinDbghttp://mtaulty.com/comm

.NET平台原理调试分析【一】WinDBG+OllyDBG by:凉游浅笔深画眉

我在.NET平台诞生了12年后才接触到它,而国内.NET平台的逆向技术兴起于10年前. 我是不幸的,不幸的是起步比前辈们晚了10年左右,十分后悔当初把最好的学习时间奉献给了游戏.最后发现,玩再多游戏也并没什么卵用. 我也是幸运的,幸运的是前人已留下了太多对.NET平台的探索脚印.我只需要跟随着他们的脚步快速前进,而不会绕很多弯路和四处碰壁. 最后感谢那些写过文章供后人学习的前辈们,虽然很多文章都是七八年前的,但受用至今. 此文既不是破解,也不讲脱壳,只是逆向角度分析.NET程序执行原理.仅希望抛

Eclipse调试Bug的七种常用技巧

1. 条件断点 断点大家都比较熟悉,在Eclipse Java 编辑区的行头双击就会得到一个断点,代码会运行到此处时停止. 条件断点,顾名思义就是一个有一定条件的断点,只有满足了用户设置的条件,代码才会在运行到断点处时停止. 在断点处点击鼠标右键,选择最后一个"Breakpoint Properties" 断点的属性界面及各个选项的意思如下图, 2. 变量断点 断点不仅能打在语句上,变量也可以接受断点, 上图就是一个变量的打的断点,在变量的值初始化,或是变量值改变时可以停止,当然变量断

android调试bug集锦 onActivityResult立即返回,并且被CANCEL

症状: 在使用startActivityForResult调用照相机或者选择图片的时候,总是onActivityResult立马返回,resultCode=0 CANCEL. startActivityForResult(intent,IMAGE_PICK_REQUEST); 因为是在fragment里面使用startActivityForResult有问题,所以开始以为是因为fragment导致的问题,各种调试都无法解决问题. 解决方法: 后来突然看到manifests里面看到activity

javascript在调试bug的奇淫技巧(Chrome, Firebug, Filddle 调试)

Fiddler Fiddler调式使用知多少(一)深入研究 微信fiddle 微信fiddle Chrome Google Chrome 官方 Chrome - 基础 Chrome - 进阶 Chrome - 性能 Chrome - 性能进阶 Chrome - 移动 Chrome - 使用技巧 Chrome - Console控制台不完全指南 Chrome - Workspace使浏览器变成IDE network面板 chrome开发工具快捷键 chrome调试工具 Chrome 开发工具 Wo

调试bug的几种方法

1.php中的dump,echo,exit 2.浏览器的f12 3.安装xdebug扩展(debugger调试器,profiler探查器,trace代码跟踪) profile日志能记录函数的执行耗时和调用关系等信息, trace日志,能够记录代码执行流程 包括时间索引,内存使用,内存增量,调用层级,函数名称,函数参数, 代码所在文件名,代码所在文件行等信息. time index:时间索引 memory usage:内存使用 memory delta:内存增量(需要开启:show_mem_del

项目调试Bug集锦(更新中)

1.解决Error: Syntax error, unrecognized expression: #tableId').load('banner.jsp') 今天在搭建SpringBoot+MBG+通用Mapper+jqGrid+maven时 报的错我找了大半天 代码都审查了好多次 都没毛病 就是一直出现这个错开发软件是:IDEA报错信息 jquery-1.11.3.min.js:2 Uncaught Error: Syntax error, unrecognized expression: