yizhu2000

--书到读透处,酒于微醺时

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  60 随笔 :: 21 文章 :: 392 评论 :: 18 Trackbacks

下面有从浅入深的6个问题,您可以尝试回答一下

  1. 一个如下的语句for (int i = 0; i < 10; i++){if (i == 5)j = 5;},什么都写在一行,你怎么在j=5前面插入断点
  2. 在一个1000次的循环体内部设置断点,你希望当循环进行到900次后中断,怎么才能做到呢?
  3. 你有一个表达式在上面循环的某一次发生了变化,你想知道是哪一次,在哪个地方,怎么才能做到?
  4. 你希望你的断点在被命中100次后,每命中三次中断一次,比如第103,第106,第109怎样做?
  5. 你有在调试一个服务程序,希望在其内部打上了断点,可是,由于这是一个公用的服务你不希望其他访问这个服务的程序被你的调试所干扰,你想怎么办?
  6. 怎样知道2个断点中断的时间间隔

问题1,2

这两个问题最简单,我在一个例子里说明

例如如下循环

for(int i=0;i<1000;i++){doSomeThing......}

在循环的大括号上单击右键,插入断点,用这个方法,可以对付那些喜欢把语句写在一行上的家伙,其实,随着.Net3.5中Linq的出现,我们肯定也会经常在在一行上写复杂的表达式,这个时候用这种插入方法会比较管用

ok,现在我们来编辑这个断点的条件,在断点上右键单击,选择如图菜单项


在弹出的窗口中可以设置断点命中的条件i==900

注意我是在调试C#代码,默认的条件语句语法是C#,如果你想切换,那就需要用Ctrl-B,来插入断点,并在弹出窗口中选择语言

通过这样设置条件断点,我们就可以解决我们的问题1,2了

 

问题3

同样通过设置条件断点我们还可以解决我们的问题3,对表达式变化的跟踪

string user="yizhu2000"

for(int i=0;i<10000;i++){

DoSomething1()

.......

DoSomethingN()

}

当循环执行完毕时我们发现user变成了"smart_boy",你不知道这个值是在第几次循环的时候变化的,那么你是不是会选择打上断点,一次一次中断,来查看呢?当然不用

在循环体结束的位置我们设置一个断点,打开条件编辑窗口(打开方法同上),设置表达式为user,勾选下面的HasChanged,也就是说,你告诉断点,当user的值发生变化时才触发

(注意:第一次执行到断点的时候,程序一定会中断,并计算这时表达式的值,所以,所谓发生变化,指的是以后执行到断点是表达式的值和第一次执行到断点时表达式的值的比较)

问题4

如何让断点在指定的命中次数或者大于某个次数时触发呢?方法是设定几个断点的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:当大于等于某数时中断

问题5

前面4个问题都已经解决了,第5个问题的解决方法是利用断点的Filter功能,比如我希望断点只有被机器名为yizhu的机器访问才能触发,我可以这样设置


当其他机器访问程序的时候,断点将不会触发,这样做的优点是通过设置机器名,我们可以让其他机器访问的时候感觉不到断点的存在,除此之外我们可以设置机器名,进程号,进程名,线程号,线程名作为filter,而且还可以把他们组合起来,比如我希望通过当机器yizhu的dllhost进程调用时才触发,那么问题就可以设置为MachineName="yizhu"&ProcessName="dllhost"

问题6

现在我们来解决第6个问题:

在程序性能调试的时候,我们经常需要知道某段代码的执行效率,一般来说,我们可以在程序中加入时间点,通过时间点相减来取得时间间隔,这种方法有个显而易见的缺点就是需要修改程序,想要不修改程序,就需要借助一些工具,那么有没有什么方法可以声明式的插入时间点,并计算值呢?其实断点完全可以做到

在给出方法前,我们来看看断点的另外一个设置项,When Hit,这个选项可以让我们在命中断点后做一些事情,包括输出一些内容,或者调用宏,比如输出一个程序中变量的值

我们输出了变量user的值,下面Continue Execution表示程序不会中断,输出后继续执行,注意表达式需要用{}括起来,,其他的部分会被作为字符串输出。设定WhenHit后断点变成了方形(看厌了圆断点,我还挺喜欢这个方家伙的)

在output中查看输出结果,如下:


既然可以计算表达式,我们的第一个最简方案就出来了,也就是在程序执行到断点的时候,输出DateTime.Now,这样当然是可行的,但是我们需要的是时间间隔,所以我们还需要自己来算个减法,还是挺麻烦的,怎么样才能让程序自己输出时间间隔呢?有一个想法是这样的,我们在上一个断点声明一个时间变量,然后在下面的断点里用DataTime.Now减去这个变量,即

断点一的条件:{DateTime _t=DateTime.Now;}

断点二的条件:{DateTime.Now-t;}

看起来不错,但是实际运行时就有问题了,让我们看看输出吧

上面高亮的部分说,变量申明只能在immediate window中进行,所以断点一的变量没有申明成功,关于immediatewindow,我们以后会涉猎到,反正就是说想在表达式里申明变量,没门,死路一条.那么我们怎么才能不申明变量又时间点呢?

这时我想起了Thread.SetData 方法,这个方法可以往当前线程专门提供的空间中插入一些数据,并且可以通过GetData得到数据,具体细节参考

http://msdn2.microsoft.com/zh-cn/library/system.threading.thread.setdata(VS.80).aspx

于是方案就有了,在第一个断点处把时间放入Thread的DataSlot,然后第二个断点取出来相减

断点一的条件:{Thread.SetData(Thread.GetNamedDataSlot("ExecutionTime"),DateTime.Now);}

断点二的条件:{DateTime.Now-(DateTime)System.Threading.Thread.GetData(System.Threading.Thread.GetNamedDataSlot("ExecutionTime"));}

看看输出效果

我们的目的已经达到了,output中成功的输出了时间间隔,当然,还不是很完善,首先,这个方法限于两个断点,你想多打几个断点,测试两两间的间隔还是比较麻烦.测量精度也可以提高,大家有兴趣可以自己研究这个方法的扩展

posted on 2007-08-03 20:03 二毛五 阅读(2696) 评论(42)  编辑 收藏 所属分类: VisualStudio

评论

#1楼  2007-08-03 20:20 xiao_p      
长见识了!
  回复  引用  查看    

看了问题就发现自己似乎不会

  回复  引用  查看    

#3楼  2007-08-03 20:33 Anders Cui      
不错!
  回复  引用  查看    

#4楼  2007-08-03 20:35 周银辉      
哇,标记一下,等会来看
  回复  引用  查看    

#5楼  2007-08-03 20:38 ˇ┾落≠單_      
不错.
  回复  引用  查看    

#6楼  2007-08-03 20:52 呵呵 [未注册用户]
确实不错
  回复  引用  查看    

#7楼  2007-08-03 20:57 代码乱了      
这不是VS2005 正式版 吧?
  回复  引用  查看    

断点condition会带来性能问题,以前用过,感觉程序执行要慢许多。可能和断点的机制有关系。不知道这样测量时间会不会准确。
  回复  引用  查看    

#9楼  2007-08-03 21:36 Justin      
如果运行环境很不容易重现,那么即时调试技巧真的是太重要了,up!
  回复  引用  查看    

#10楼  2007-08-03 21:55 戏水      
这个真的不错 ,希望多写一些这类文章。提高工作效率
  回复  引用  查看    

#11楼  2007-08-03 22:01 ken [未注册用户]
好文!
  回复  引用  查看    

#12楼  2007-08-03 22:01 JohnnyHu [未注册用户]
1 2 貌似2003就有的了
其他的等于自己写个
if somelogic() then
debuger.break()
end if
  回复  引用  查看    

#13楼  2007-08-03 22:06 Koy [未注册用户]
呵呵,,只用过1、2!
  回复  引用  查看    

#14楼  2007-08-03 22:18 cnlamar      
yizhu2000哈哈
  回复  引用  查看    

#15楼  2007-08-03 22:42 宋国安      
回头推荐给team。
  回复  引用  查看    

#16楼  2007-08-03 22:48 Cat Chen      
以前还不知道能够有那么多细节设置呢,仅仅知道其中的一小部分。
  回复  引用  查看    

#17楼  2007-08-03 23:25 marxTen      
确实是好东西~~~
  回复  引用  查看    

#18楼  2007-08-03 23:38 qufo      
只用过 1,2
  回复  引用  查看    

#19楼  2007-08-04 08:40 随风流月      
@Cat Chen
前几天我刚刚研究出来的,还可以用 When Hit 记录日志。
  回复  引用  查看    

#20楼  2007-08-04 08:52 yunhuasheng      
不错,看来很多功能我还是没用到.
  回复  引用  查看    

#21楼  2007-08-04 08:57 yinh      
好文章,不过有时在debug状态下的时间和实际运行时间有很大的差异,好像尤其是在调用了com组件的时候
  回复  引用  查看    

#22楼  2007-08-04 09:11 Reson [未注册用户]
学习了!
  回复  引用  查看    

#23楼  2007-08-04 10:55 路人甲 [未注册用户]
很实用,谢谢楼主
  回复  引用  查看    

#24楼  2007-08-04 11:00 S.Sams      
不错!
  回复  引用  查看    

#25楼  2007-08-04 11:22 江城子      
好文章啊,我一直以为需要外部工具还控制断点,没想到vs本身就有这个功能,楼主你早写这个文章多好啊
  回复  引用  查看    

#26楼  2007-08-04 13:48 JustDI      
收藏了~~
  回复  引用  查看    

#27楼  2007-08-04 14:21 淡泊江湖      
不错的经验技巧,谢谢分享!
  回复  引用  查看    

#28楼  2007-08-04 15:45 二毛五 [未注册用户]
优秀的程序员,除了思想,细节也很重要,所以希望多一些朴实无华的交流
http://www.cnblogs.com/yizhu2000/archive/2007/07/05/807288.aspx
  回复  引用  查看    

#29楼  2007-08-04 16:13 Z [未注册用户]
不错
  回复  引用  查看    

#30楼  2007-08-04 16:33 小哈      
還是有點麻煩
前幾年用PowerBuilder時if inta=100 then debugbreak()就可以了
  回复  引用  查看    

#31楼  2007-08-04 19:56 丁学      
越来越感觉自己像个白痴,郁闷
上次是老赵,这次是你……

  回复  引用  查看    

通常都不用。
如果需要条件断点,一般都会选择自己的custom_assert宏。这个比编译器的要快的多。
  回复  引用  查看    

#33楼  2007-08-04 21:26 韩国队 [未注册用户]
确实强


http://www.wfsoft.com/wf_wfChart.asp
  回复  引用  查看    

#34楼  2007-08-05 04:03 木野狐(Neil Chen)      
不错!
  回复  引用  查看    

#35楼  2007-08-05 10:33 墨尔      
不错,
  回复  引用  查看    

#36楼  2007-08-06 08:31 大石头      
又学到好东西了
  回复  引用  查看    

#37楼  2007-08-06 13:17 Ricky [未注册用户]
总结的很棒,谢谢 :)
  回复  引用  查看    

#38楼  2007-08-14 16:41 公木子      
不错,细节决定成败,调了这么久今天长见识了。
  回复  引用  查看    

#39楼  2007-08-21 16:45 dmh [未注册用户]
非常好!!!!!!!!!!!!!!!!!!!!!!!!!!
  回复  引用  查看    

#40楼  2007-12-08 18:01 沙加      
俺好象没用过断点这个功能~~~:(
  回复  引用  查看    

#41楼  2008-01-30 15:29 AK47      
很好!以前没注意这点!
  回复  引用  查看    

#42楼  2008-04-03 09:26 破曉之陽      
嘿嘿。。英文版的。
  回复  引用  查看    


标题  
姓名  
主页
Email (只有博主才能看到) 
验证码 *  看不清,换一张
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论  新用户注册  返回页首  恢复上次提交      
该文被作者在 2007-12-05 11:22 编辑过
 
向地震灾区捐赠爱心