Visual Studio的调试技巧

Visual Studio的调试技巧

【原文地址】 Debugging Tips with Visual Studio 2010

【原文发表日期】 2010/8/19 10:48 AM

 

这是我写的关于VS2010和.Net4发布的博客系列的第26篇。

今天的博文包含了一些有用的能用于VS的调试技巧。 我的朋友 Scott Cate(他写了很多很好的关于VS使用技巧和窍门的 博客)最近向我强调了这些很好的技巧,大部分使用VS的开发人员好像不知道这些技巧(即使他们大部分都在产品开发组呆过一阵子)。 如果你还没有使用过这些技巧,希望这篇博文能帮你发现它们。 它们学起来很容易,能帮你节省很多时间。

运行到光标(Ctrl+ F10)

我经常看见人们是这样来调试应用程序的: 他们在应用程序需要调试的代码前设置一个断点,然后反复的敲F10/F11来逐步通过代码,直到到达他们真正想要研究的确切位置。有些时候他们需要仔细观察所跨过的每行代码,这样使用F10/F11 就很合理。 但是更普遍的是,他们只想快点进入他们真正关心的那行代码——这是使用F10/F11 就不是最好的选择了。

相反, 你可能想利用调试器支持的特性“运行到光标”。 只需简单地把你的光标放在代码中你想程序运行到的那一行,然后同时敲Ctrl+F10。这样程序就会运行到光标所在的那一行, 然后执行中止,由调试器控制——这样就节约了你反复敲击F10/F11到达那里的时间。即使你想运行到的那行代码不在当前调试的方法或类里,而是在一个独立的方法或类里,这也同样奏效。

条件断点

我们经常在可用性学习中见到另一个普遍的技巧:开发人员设置断点,运行程序,试着输入一些数据,当到达一个断点时,手工检查某种条件是不是成立,如果成立才决定进一步研究。 如果条件不符合他们想要的, 按F5继续执行程序,尝试另外一些输入,再手工重复同样的过程。

VS的条件断点功能提供了一个更加容易的方法来处理以上情况。 条件断点允许你只在某种明确指定的条件成立时才中止执行,由调试器控制。这帮你免于手动检查/恢复你的程序, 使得整个调试过程免去许多手工活,也不那么冗长乏味。

设置一个条件断点

设置一个条件断点十分简单,在代码里按F9为某一行设置一个断点:

然后右击断点——编辑器左边的红色圆圈,在右键菜单中,选择“条件…” :

将弹出以下对话框, 允许你指明某种条件,只有当这种条件成立时,断点才能达到。 例如:我们可以通过写下面的表达式来指明,只有当paginatedDinners列表元素的个数小于10时,才中止程序,由调试器控制。

现在, 当我重新运行程序来研究一下, 调试器只在这个查找返回值小于10时,才中止程序执行。 如果返回值不小于10 ,将不会触发断点。

命中次数功能

有时你只想在条件第N次成立时中止执行。例如:仅当第5次出现查找返回值小于10时,才中止执行。你这样启用这个功能:右击断点, 选择“命中次数…”菜单命令。

将弹出以下对话框, 允许你指明程序中断的条件:条件被第N次满足时,或者条件被满足的次数是N的倍数时,或者条件被满足的次数大于等于N次时。

机器/线程/进程筛选器

你可以右击断点,选择“筛选器…”菜单命令, 来指明断点只在某台特定的机器,或某个特定的进程或线程中才能被触发。

跟踪点——当击中断点时自定义行为

很多人不知道的一个调试功能是使用 跟踪点。 跟踪点是一个断点, 当它被击中时,某种自定义的宏会被触发执行。当你想研究你的应用程序而又不想中止执行程序时, 这个功能特别有用。

我将用一个简单的控制台程序来演示如何使用跟踪点。 下面是 斐波那契数列的递归实现:

在上面的应用程序中,针对特定的输入,我们使用Console.WriteLine()来输出最后的斐波那契数列。假如我们想在调试过程中研究斐波那契的递归过程——而不停止调试的执行? 跟踪点能帮我们很轻松地做到这一点。

设置跟踪点

你可以这样启用跟踪点:按F9在代码上设置一个断点, 右击断点,在右键菜单中选择“命中条件…”菜单命令:

将弹出以下对话框——允许你指定当断点触发时,进行何种操作:

如上所示,我们指定每次当断点的条件成立时,打印跟踪信息。注意我们指定了想要输出的局部变量“X” 的值作为输出信息的一部分。 局部变量能通过{变量名}的语法被引用。 也有内嵌的命令(像$CALLER,$CALLSTACK, $FUNCTION等等)可以用来输出跟踪信息中常见的值。

上面对话框的底部, 我们也选中了“继续执行”单选框——表示我们不希望调试器暂停程序。 相反,程序会继续执行——只是我们自定义的跟踪信息会在每次断点条件满足时输出,就这点不同。

现在当我们运行程序时,我们会发现自定义的跟踪信息会自动出现在VS的输出窗口中——使我们能看到程序的递归过程。

你也可以选择为你的程序设置一个自定义跟踪监听器——这样跟踪点的输出信息就会被重定向到它里面,而不是VS的输出窗口里。

跟踪点——运行自定义的宏

上周我在伦敦做了一次演讲, 听众中有个人问了这样一个问题:有没有可能当击中一个跟踪点时,自动输出所有的局部变量。

这个功能不是内置在VS中的, 但是可以通过在VS中写一个自定义的宏来启用它,然后设置一个跟踪点,当它被击中时,调用这个宏。 为了实现这个目的, 打开VS中的宏窗口(工具->宏->宏菜单命令)。然后在项目管理器“MyMacros”结点下面, 选择模板或者新建一个模板(如:添加一个名为“UsefulThings”的 模板), 再将下面的VB宏代码贴到模板里,并保存它:

Sub DumpLocals()

Dim outputWindow As EnvDTE.OutputWindow

        outputWindow = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput).Object

Dim currentStackFrame As EnvDTE.StackFrame

        currentStackFrame = DTE.Debugger.CurrentStackFrame

        outputWindow.ActivePane.OutputString("*Dumping Local Variables*" + vbCrLf)

For Each exp As EnvDTE.Expression In currentStackFrame.Locals

            outputWindow.ActivePane.OutputString(exp.Name + " = " + exp.Value.ToString() + vbCrLf)

Next

End Sub

上面的宏代码依次检测当前堆栈,获取所有的局部变量,并将其显示在输出窗口。

使用DumpLocals自定义宏

在下面这个简单的应用程序中,我们可以利用自定义的“DumpLocals”宏:

在上面的Add方法的return语句上,按F9设置一个断点。 右击断点,选择“命中条件…”菜单命令:

将弹出以下对话框,上例中,我们选中了“打印信息”的单选框,再手工指定希望输出的变量, 而这里, 我们选中“运行宏”的单选框,使它指向我们创建的自定义宏UsefulThings.DumpLocals:

我们仍然选中“继续执行”单选框,这样能保证当跟踪点被击中时,程序依然能够继续执行。

运行程序

现在当我们按F5运行程序,当调用Add方法时,我们将看见以下输出出现在VS输出窗口中。 注意当跟踪点被击中时,宏是如何自动列出各个变量名及其值的。

总结

VS调试器功能非常丰富。 我强烈建议大家抽出一些时间来学习它的所有功能。 以上的技巧和诀窍只是很多大家没有真正意识到的功能中的一小部分。

我之前写过其他一些 关于VS2010调试器改进的博客(包括数据标签固定,断点导入导出,保留最后值变量, 等等)。 我将发表更多关于VS2010的智能跟踪和转储文件调试支持的博文。这些技术提供了很多非常酷的新功能,会让程序(包括产品中的程序)的调试变得非常简单和强大。

也请务必看看Scott Cate很棒的 VS2010技巧和诀窍系列,你可以学习如何更好的利用VS。他有一些非常棒的免费视频和博客。

也要看看Jim Griesmer很棒的 VS调试技巧和诀窍系列。 他有许多很好的可以利用的技巧和诀窍。

希望这能对您有所帮助。

Scott

转载于:https://www.cnblogs.com/yymn/p/5341945.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/272052.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

读者写者问题

河北科技大学操作系统课程设计——读者写者问题 #include <windows.h> #include <conio.h> #include <stdlib.h> #include <fstream> #include <io.h> #include <string.h> #include <stdio.h> using namespace std; #define READE…

Linux排序命令sort笔记

很多时候Linux需要对文本相对比较规范的文本数据进行排序&#xff0c;这时候可以使用Linux系统下的sort命令进行处理。语法格式&#xff1a;sort [-ntkr] filename常用参数&#xff1a;-n 根据数字进行排序-t 指定的分隔符-k 指定分隔符的第几列-r 降序排序用法示例&#xff1a…

《过早退出是一切失败的根源》读后感

在看完周筠老师的文章&#xff1a;过早的退出是一切失败的根源&#xff0c;内心感触颇大。因为年轻&#xff0c;我们总觉得有许许多多的另一个与下一次&#xff0c;我们总是在某个环境里失败或觉得不行时&#xff0c;就会想退出&#xff0c;我们对有风险的事情不愿去尝试&#…

redirect路由配置 vue_Web前端:Vue路由进阶配置

大家好&#xff0c;我来了&#xff0c;本期为大家带来的前端开发知识是”Web前端&#xff1a;Vue路由进阶配置“&#xff0c;有兴趣做前端的朋友&#xff0c;和我一起来看看吧&#xff01;1. 页面打开权限流程页面是否能打开有以下两点判断&#xff1a;1. 判断是否增加登陆的判…

ESP8266模块无限重启崩溃的问题

问题背景&#xff1a; 最近使用ESP8266模块&#xff08;NodeMCU&#xff09;在Arduino环境下进行开发调试时遇到了一个ESP8266模块无限重启崩溃的问题。这个问题不是第一次发生了&#xff0c;很久之前遇到了后面也不知道怎么解决了。 这一次再次碰到了&#xff0c;经过查阅网上…

python格式化输出

格式化输出字符串 格式化输出整数 格式化输出浮点数 输出&

Linux常用内建命令笔记

Linux系统为了便于运维人员对系统的操作&#xff0c;所以内建了很多shell命令。一般来说linux系统的内建命令会比执行外部的shell命令执行更快。因为执行内建命令相当于调用当前shell进程里面的函数&#xff0c;而执行外部命令的话需要出发IO操作还要fork一个单独的进程来执行&…

什么原因接触接触impala的

最近一个项目&#xff0c;关于大数据的改造项目&#xff0c;底层选择Impala还是sparkSQL呢&#xff1f; 最后选择Impala.这样就开启了我的Impala学习之旅。我大部分负责Imapa接口开发工作。 我是控制不住的想整个都了解和学习。所有还在impala控制台各种测试和学习。差不多一两…

asp手机拍照显示_会员动态飞凯材料120吨TFTLCD混合液晶显示项目,建后五年达产...

来源 &#xff1a;全景网10月26日&#xff0c;在飞凯材料可转债发行网上路演会议上&#xff0c;该公司相关人员也对投资者关心的问题进行解答。关于发行8.25亿元可转换债券&#xff0c;飞凯材料表示本次募集资金扣除发行费用后将用于投资以下项目&#xff1a;10000t/a紫外固化光…

python中变量的命名和关键字和变量的命名规则

[False, None, True, and, as, assert, break, class, continue, def, del, elif, else, except, finally, for, from, global, if, import, in, is, lambda, nonlocal, not, or, pass, raise, return, try, while, with, yield]

Linux中Shell数组的笔记

Shell数组的介绍数组算是一种特殊的数据结构&#xff0c;数据项可以成为数组的元素&#xff0c;可以通过数组的索引获取每一个数组的元素值。数组的典型的使用场景是把相同类型的元素汇总在一起。由于Shell变量属于弱类型&#xff0c;所以数组里面的元素并不一定是相同类型。注…

linux中php配置

安装nginxphp好久了&#xff0c;今天意外的搭建好了&#xff0c;分享给大家 &#xff0c;以免以后多走弯路。 nginx已经前面安装好了&#xff0c;现在就开始配置php 安装php 分为两个部分 &#xff1a;一部分是php源码&#xff0c;另外是fastcgi管理进程&#xff1a;php-fpm 庆…

log函数 oracle power_Excel之数学函数SQRT/MOD/EXP/LN/RAND

本部分主要包括ABS函数、SQRT函数、SIGN函数、MOD函数、POWER、EXP函数、LN函数、LOG函数、LOG10函数、RAND函数、RANDBETWEEN函数、PI函数、SIN函数、COS函数、TAN函数、PRODUCT函数、FACT函数、GCD函数、LCM函数、DEGREES函数、RADIANS函数和SUBTOTAL函数共22个。需重点掌握S…

Linux中Shell循环结构for用法笔记

Shell中可以使用for做固定次数循环的处理。常见的for循环用法主要有以下几种&#xff1a;1、带列表的for循环语法结构&#xff1a;for item in (list)docommanddone示例&#xff1a;cat demo1.sh 内容如下&#xff1a;#!/bin/bashnames"小明 小王 小张"for item in n…

斐波那契数列 在实际问题上的变种

我们可以用2*1的小矩形横着或者竖着去覆盖更大的矩形。请问用n个2*1的小矩形无重叠地覆盖一个2*n的大矩形&#xff0c;总共有多少种方法1 利用数组结构遍历方法if(target1 || target0)return 1;int [] arr new int [target1];arr[0] 1;arr[1] 1;for(int i2;i<target;i){a…

焊接符号标注图解示例_【干货】焊接图纸符号汇总 ,学习收藏!!

基本坡口符号坡口符号(注&#xff1a;图中“破”应为“坡”)焊接图纸符号标注图解示例焊接符号标注实例及方法在焊接结构图样上&#xff0c;焊接方法可按国家标准GB5185-85的规定用阿拉伯效字表示&#xff0c;标注在指引线的尾部。常用焊接方法代号见表3-9所示。如果是组合焊接…

Linux有关Shell中if用法笔记

shell中的if主要是用于程序的判断逻辑&#xff0c;从而控制脚本的执行逻辑。这和很多编程语言思路上都是一致的。1、if的用法结构如下&#xff1a;if exp;thencommand1;command2;fi示例&#xff1a;#根据输入的学生成绩打印对应的成绩等级&#xff1a;大于90分为优秀&#xff1…

自定义Chrome插件Vimium

自定义快捷键 map e scrollPageUp map w removeTab map s nextTab map a previousTab map q goNext map z restoreTab 默认搜索引擎 https://www.baidu.com/s?wd 添加上一页下一页识别 Previous patterns prev,previous,back,older,<,←,,≪,<<,上一页 Next patterns…