当前位置: 首页 > news >正文

VS2008调试技巧集合

下面有从浅入深的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 < 10; i++){if (i == 5)j = 5;},什么都写在一行,你怎么在j=5前面插入断点 在一个1000次的循环体内部设置断点,你希望当循环进行到900次后中断,怎么才能做到呢?
这两个问题最简单,我在一个例子里说明
例如如下循环
for(int i=0;i<1000;i++){doSomeThing......}
在循环的大括号上单击右键,插入断点,用这个方法,可以对付那些喜欢把语句写在一行上的家伙,其实,随着.Net3.5中Linq的出现,我们肯定也会经常在在一行上写复杂的表达式,这个时候用这种插入方法会比较管用
ok,现在我们来编辑这个断点的条件,在断点上右键单击,选择如图菜单项

VS2008调试技巧集合 - 無牽℡↘嘸褂 - 菁华隐没℡↘芳流歇绝
在弹出的窗口中可以设置断点命中的条件i==900
VS2008调试技巧集合 - 無牽℡↘嘸褂 - 菁华隐没℡↘芳流歇绝
注意我是在调试C#代码,默认的条件语句语法是C#,如果你想切换,那就需要用Ctrl- B,来插入断点,并在弹出窗口中选择语言
VS2008调试技巧集合 - 無牽℡↘嘸褂 - 菁华隐没℡↘芳流歇绝
通过这样设置条件断点,我们就可以解决我们的问题1,2了
 
问题3
你有一个表达式在上面循环的某一次发生了变化,你想知道是哪一次,在哪个地方,怎么才能做到? 
同样通过设置条件断点我们还可以解决我们的问题3,对表达式变化的跟踪
string user="yizhu2000"
for(int i=0;i<10000;i++){
DoSomething1()
.......
DoSomethingN()
}
当循环执行完毕时我们发现user变成了"smart_boy",你不知道这个值是在第几次循环的时候变化的,那么你是不是会选择打上断点,一次一次中断,来查看呢?当然不用
在循环体结束的位置我们设置一个断点,打开条件编辑窗口(打开方法同上),设置表达式为 user,勾选下面的HasChanged,也就是说,你告诉断点,当user的值发生变化时才触发
VS2008调试技巧集合 - 無牽℡↘嘸褂 - 菁华隐没℡↘芳流歇绝
(注意:第一次执行到断点的时候,程序一定会中断,并计算这时表达式的值,所以,所谓发生变化,指的是以后执行到断点是表达式的值和第一次执行到断点时表达式的值的比较)
问题4
你希望你的断点在被命中100次后,每命中三次中断一次,比如第103,第106,第109怎样做? 
如何让断点在指定的命中次数或者大于某个次数时触发呢?方法是设定几个断点的 HitCount,右键单击断点,在弹出菜单中选择Hit Count,会弹出如下窗口
VS2008调试技巧集合 - 無牽℡↘嘸褂 - 菁华隐没℡↘芳流歇绝
在"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的机器访问才能触发,我可以这样设置
VS2008调试技巧集合 - 無牽℡↘嘸褂 - 菁华隐没℡↘芳流歇绝
当其他机器访问程序的时候,断点将不会触发,这样做的优点是通过设置机器名,我们可以让其他机器访问的时候感觉不到断点的存在,除此之外我们可以设置机器名,进程号,进程名,线程号,线程名作为filter,而且还可以把他们组合起来,比如我希望通过当机器yizhu的dllhost进程调用时才触发,那么问题就可以设置为MachineName="yizhu"&ProcessName="dllhost"
问题6  怎样知道2个断点中断的时间间隔 
现在我们来解决第6个问题:
在程序性能调试的时候,我们经常需要知道某段代码的执行效率,一般来说,我们可以在程序中加入时间点,通过时间点相减来取得时间间隔,这种方法有个显而易见的缺点就是需要修改程序,想要不修改程序,就需要借助一些工具,那么有没有什么方法可以声明式的插入时间点,并计算值呢?其实断点完全可以做到
在给出方法前,我们来看看断点的另外一个设置项,When Hit,这个选项可以 VS2008调试技巧集合 - 無牽℡↘嘸褂 - 菁华隐没℡↘芳流歇绝 让我们在命中断点后做一些事情,包括输出一些内容,或者调用宏,比如输出一个程序中变量的值
VS2008调试技巧集合 - 無牽℡↘嘸褂 - 菁华隐没℡↘芳流歇绝
我们输出了变量user的值,下面Continue Execution表示程序不会中断,输出后继续执行,注意表达式需要用{}括起来,,其他的部分会被作为字符串输出。设定WhenHit后断点变成了方形(看厌了圆断点,我还挺喜欢这个方家伙的)
在output中查看输出结果,如下:
VS2008调试技巧集合 - 無牽℡↘嘸褂 - 菁华隐没℡↘芳流歇绝
既然可以计算表达式,我们的第一个最简方案就出来了,也就是在程序执行到断点的时候,输出 DateTime.Now,这样当然是可行的,但是我们需要的是时间间隔,所以我们还需要自己来算个减法,还是挺麻烦的,怎么样才能让程序自己输出时间间隔呢?有一个想法是这样的,我们在上一个断点声明一个时间变量,然后在下面的断点里用DataTime.Now减去这个变量,即
断点一的条件:{DateTime _t=DateTime.Now;}
断点二的条件:{DateTime.Now-t;}
看起来不错,但是实际运行时就有问题了,让我们看看输出吧
VS2008调试技巧集合 - 無牽℡↘嘸褂 - 菁华隐没℡↘芳流歇绝
上面高亮的部分说,变量申明只能在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"));}
看看输出效果
VS2008调试技巧集合 - 無牽℡↘嘸褂 - 菁华隐没℡↘芳流歇绝

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





     本文转自My_King1 51CTO博客,原文链接:http://blog.51cto.com/apprentice/1360783,如需转载请自行联系原作者




相关文章:

  • VelocityTracker简介
  • 基于Netty4的HttpServer和HttpClient的简单实现
  • Centos6.8安装Gitlab7.6
  • 大规模分布式系统问题集及解决方案(学习)
  • php发送短信验证码完成注册功能
  • Struts2国际化-getText()方法
  • WDS部署服务之二镜像导入
  • 20170118修改商品流水
  • 如何轻松运维,你是救火队员还是工程师?
  • CentOS6.7 mysql 主从配置
  • Zookeeper的zoo.cfg的配置
  • 编写一个简单通用的makefile
  • ORA-00119: invalid specification for system parameter REMOTE_LISTENER
  • bootstrap-水平表单
  • MYSQL数据库字符编码设置
  • 【node学习】协程
  • 2017-09-12 前端日报
  • canvas 绘制双线技巧
  • gf框架之分页模块(五) - 自定义分页
  • JS字符串转数字方法总结
  • k8s 面向应用开发者的基础命令
  • Solarized Scheme
  • 如何解决微信端直接跳WAP端
  • 腾讯优测优分享 | 你是否体验过Android手机插入耳机后仍外放的尴尬?
  • 扩展资源服务器解决oauth2 性能瓶颈
  • #pragma 指令
  • (02)Cartographer源码无死角解析-(03) 新数据运行与地图保存、加载地图启动仅定位模式
  • (1)常见O(n^2)排序算法解析
  • (145)光线追踪距离场柔和阴影
  • (附源码)python旅游推荐系统 毕业设计 250623
  • (附源码)ssm旅游企业财务管理系统 毕业设计 102100
  • (附源码)小程序 交通违法举报系统 毕业设计 242045
  • (黑马出品_高级篇_01)SpringCloud+RabbitMQ+Docker+Redis+搜索+分布式
  • (循环依赖问题)学习spring的第九天
  • (转)关于pipe()的详细解析
  • ******IT公司面试题汇总+优秀技术博客汇总
  • .apk 成为历史!
  • .equal()和==的区别 怎样判断字符串为空问题: Illegal invoke-super to void nio.file.AccessDeniedException
  • .MyFile@waifu.club.wis.mkp勒索病毒数据怎么处理|数据解密恢复
  • .NET CF命令行调试器MDbg入门(三) 进程控制
  • .NET中统一的存储过程调用方法(收藏)
  • @RequestBody详解:用于获取请求体中的Json格式参数
  • [ JavaScript ] JSON方法
  • [3D游戏开发实践] Cocos Cyberpunk 源码解读-高中低端机性能适配策略
  • [Angular 基础] - 表单:响应式表单
  • [Angular 基础] - 数据绑定(databinding)
  • [AutoSar]工程中的cpuload陷阱(三)测试
  • [Flutter] extends、implements、mixin和 abstract、extension的使用介绍说明
  • [GN] Vue3.2 快速上手 ---- 核心语法2
  • [Hadoop in China 2011] Hadoop之上 中国移动“大云”系统解析
  • [Java] 模拟Jdk 以及 CGLib 代理原理
  • [Jenkins] Docker 安装Jenkins及迁移流程
  • [JS7] 显示从0到99的100个数字
  • [LeetCode]—Simplify Path 简化路径表达式
  • [node]Node.js 模块系统