《vs2008调试技巧.doc》由会员分享,可在线阅读,更多相关《vs2008调试技巧.doc(20页珍藏版)》请在金锄头文库上搜索。
1、 VS2005调试技巧集合http:/ 一个如下的语句for (int i = 0; i 10; i+)if (i = 5)j = 5;,什么都写在一行,你怎么在j=5前面插入断点2. 在一个1000次的循环体内部设置断点,你希望当循环进行到900次后中断,怎么才能做到呢?3. 你有一个表达式在上面循环的某一次发生了变化,你想知道是哪一次,在哪个地方,怎么才能做到?4. 你希望你的断点在被命中100次后,每命中三次中断一次,比如第103,第106,第109怎样做?5. 你有在调试一个服务程序,希望在其内部打上了断点,可是,由于这是一个公用的服务你不希望其他访问这个服务的程序被你的调试所干扰,你
2、想 怎么办?6. 怎样知道2个断点中断的时间间隔问题1,21. 一个如下的语句for (int i = 0; i 10; i+)if (i = 5)j = 5;,什么都写在一行,你怎么在j=5前面插入断点2. 在一个1000次的循环体内部设置断点,你希望当循环进行到900次后中断,怎么才能做到呢?这两个问题最简单,我在一个例子里说明例如如下循环for(int i=0;i1000;i+)doSomeThing.在循环的大括号上单击右键,插入断点,用这个方法,可以对付那些喜欢把语句写在一行上的家 伙,其实,随着.Net3.5中Linq的出现,我们肯定也会经常在在一行上写复杂的表达式,这个时候用这种
3、插入方法会比较管用ok,现在我们来编辑这个断点的条件,在断点上右键单击,选择如图菜单项在弹出的窗口中可以设置断点命中的条件i=900注意我是在调试C#代码,默认的条件语句语法是C#,如果你想切换,那就需要用Ctrl- B,来插入断点,并在弹出窗口中选择语言通过这样设置条件断点,我们就可以解决我们的问题1,2了问题3你有一个表达式在上面循环的某一次发生了变化,你想知道是哪一次,在哪个地方,怎么才能做到?同样通过设置条件断点我们还可以解决我们的问题3,对表达式变化的跟踪string user=yizhu2000for(int i=0;i10000;i+)DoSomething1().DoSomet
4、hingN()当循环执行完毕时我们发现user变成了smart_boy,你不知道这个值是在第几次 循环的时候变化的,那么你是不是会选择打上断点,一次一次中断,来查看呢?当然不用在循环体结束的位置我们设置一个断点,打开条件编辑窗口(打开方法同上),设置表达式为 user,勾选下面的HasChanged,也就是说,你告诉断点,当user的值发生变化时才触发(注意:第一次执行到断点的时候,程序一定会中断,并计算这时表达式的值,所以,所谓发生变 化,指的是以后执行到断点是表达式的值和第一次执行到断点时表达式的值的比较)问题4你希望你的断点在被命中100次后,每命中三次中断一次,比如第103,第106,
5、第109怎样做?如何让断点在指定的命中次数或者大于某个次数时触发呢?方法是设定几个断点的 HitCount,右键单击断点,在弹出菜单中选择Hit Count,会弹出如下窗口在when the break point is hit下拉列表里,我们可以看到四个选项break always:总是中断break when the hit count is equal to:等于某次数时中断beak when the hit count is a multpile of:当次数是某数的倍数时中断break when the hit count is greater than or equal to:当大
6、于等于某数时中断问题5你有在调试一个服务程序,希望在其内部打上了断点,可是,由于这是一个公用的服务你不希望其他访问这个服务的程序被你的调试所干扰,你想 怎么办?前面4个问题都已经解决了,第5个问题的解决方法是利用断点的Filter功能,比如我希望 断点只有被机器名为yizhu的机器访问才能触发,我可以这样设置当其他机器访问程序的时候,断点将不会触发,这样做的优点是通过设置机器名,我们可以让其他 机器访问的时候感觉不到断点的存在,除此之外我们可以设 置机器名,进程号,进程名,线程号,线程名作为filter,而且还可以把他们组合起来,比如我希望通过当机器yizhu的dllhost进程调用时才触 发
7、,那么问题就可以设置为MachineName=yizhu&ProcessName=dllhost问题6 怎样知道2个断点中断的时间间隔现在我们来解决第6个问题:在程序性能调试的时候,我们经常需要知道某段代码的执行效率,一般来说,我们可以在程序中加 入时间点,通过时间点相减来取得时间间隔,这种方法有个 显而易见的缺点就是需要修改程序,想要不修改程序,就需要借助一些工具,那么有没有什么方法可以声明式的插入时间点,并计算值呢?其实断点完全可以做到在给出方法前,我们来看看断点的另外一个设置项,When Hit,这个选项可以让我们在命中断点后做一些事情,包括输出一 些内容,或者调用宏,比如输出一个程序中
8、变量的值我们输出了变量user的值,下面Continue Execution表示程序不会中断,输出后继续执行,注意表达式需要用括起来,,其他的部分会被作为字符串输出。设定WhenHit后断点变成了方 形(看厌了圆断点,我还挺喜欢这个方家伙的)在output中查看输出结果,如下:既然可以计算表达式,我们的第一个最简方案就出来了,也就是在程序执行到断点的时候,输出 DateTime.Now,这样当然是可行的,但是我们需 要的是时间间隔,所以我们还需要自己来算个减法,还是挺麻烦的,怎么样才能让程序自己输出时间间隔呢?有一个想法是这样的,我们在上一个断点声明一个时间 变量,然后在下面的断点里用Data
9、Time.Now减去这个变量,即断点一的条件:DateTime _t=DateTime.Now;断点二的条件:DateTime.Now-t;看起来不错,但是实际运行时就有问题了,让我们看看输出吧上面高亮的部分说,变量申明只能在immediate window中进行,所以断点一的变量没有申明成功,关于immediatewindow,我们以后会涉猎到,反正就是说想在表达式里申明变量,没门,死 路一条.那么我们怎么才能不申明变量又时间点呢?这时我想起了Thread.SetData 方法,这个方法可以往当前线程专门提供的空间中插入一些数据,并且可以通过GetData得到数据,具体细节参考http:/
10、取出来相减断点一的条件: Thread.SetData(Thread.GetNamedDataSlot(ExecutionTime),DateTime.Now);断点二的条件: DateTime.Now-(DateTime)System.Threading.Thread.GetData(System.Threading.Thread.GetNamedDataSlot(ExecutionTime);看看输出效果我们的目的已经达到了,output中成功的输出了时间间隔,当然,还不是很完善,首先,这 个方法限于两个断点,你想多打几个断点,测试两两间的间隔还是比较麻烦.测量精度也可以提高,大家有兴趣可
11、以自己研究这个方法的扩展=高效编程十八式(11/13)调试http:/ C+某些语句的作用不太熟悉,对某个库函数的作用不太熟悉,调试一下,就可以看得清清楚楚了。如果程序只是逻辑出错误,最好的方法是测试,通过逐个单元 的测试,找出问题的所在。为什么测试的效率更高?因为测试可以是自动化的,你可以编写测试代码,一次性地完成很多测试,但调试只能一步一步地来。调试的好 处是可以直接看变量的值,而测试的话,必须写额外的代码把变量的值输出到控制台或者日志文件里。下面说一些调试的技巧。断点最简单的一种,设置一个断点,程序执行到那一句就自动中断进入调试状态。单步执行有三种,一种是每次执行一行;一种是每次执行一行
12、,但遇到函数调用就会跳到被调用的函数里;一种是直接执行当前函数里剩下的指令,返回上一级函数。在 Visual Studio中,上面三种方法对应的快捷键分别为F10、F11、Shift+F11。监视调试器可能会自动列出一些相关变量的值,但是你可能还关心其它变量的值,可以添加对这些变量的监视。还可以监视一个表达式的值,比如a+b。但是,这个表 达式最好不要修改变量的值,比如监视a+都会导致监视时修改了a的值,影响了程序的运行结果。条件中断假如你有这样的循环:for(int i=0;i100;i+)for(int j=0;j100;j+)你怀疑当i=10且j=10的时候执行有问题,那如何调试?用断点
13、的话,从i=0的初始状态,需要中断10次才能到i=10,然后从j=0也需要再中断 10次,才能到j=10的状态。所以想进入i=10且j=10的状态,需要中断20次,这太麻烦了。可以使用条件中断:for(int i=0;i100;i+)for(int j=0;j100;j+)if(i=10 & j=10);/空语句在空语句的那一行设置断点就可以了。上面的if结构太占地方,还可以用assert:assert(i!=10 | j!=10);断言i不为10或j不为10,那么当i=10且j=10的时候,断言就不成立,程序就会中断,进入调试状态。有时候用throw也可以中断:if(i=10 & j=10)throw;但是最好不要这样做,调试器不一定会在throw的地方中断。控制变量法其实这已经不算是调试的内容了,但是也是一种找出bug原因的手段,所以还是在这里说。控制变量法常用于科学研究中,比如说,研究牛顿第二定律a=F/m,a与F和m都有关,那么可以先固定m,研究a与F的关系;然后固定F,研究m与a的关 系。对于一个程序来说,一个bug可能跟多处代码有关。假如你怀疑这个bug与某些语句有关,可以