这是我写的关于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宏代码贴到模板里,并保存它:

   1: Sub DumpLocals()
   2:  
   3: Dim outputWindow As EnvDTE.OutputWindow
   4:  
   5:        outputWindow = DTE.Windows.Item(EnvDTE.Constants.vsWindowKindOutput).Object
   6:  
   7: Dim currentStackFrame As EnvDTE.StackFrame
   8:  
   9:        currentStackFrame = DTE.Debugger.CurrentStackFrame
  10:  
  11:        outputWindow.ActivePane.OutputString("*Dumping Local Variables*" + vbCrLf)
  12:  
  13: For Each exp As EnvDTE.Expression In currentStackFrame.Locals
  14:  
  15:            outputWindow.ActivePane.OutputString(exp.Name + " = " + exp.Value.ToString() + vbCrLf)
  16:  
  17: Next
  18:  
  19: End Sub

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

使用DumpLocals自定义宏

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

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

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

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

运行程序

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

总结

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

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

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

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

【.Net】Visual Studio的调试技巧的更多相关文章

  1. Visual Studio的调试技巧

    Visual Studio的调试技巧 [原文地址] Debugging Tips with Visual Studio 2010 [原文发表日期] 2010/8/19 10:48 AM 这是我写的关于 ...

  2. Visual Studio 使用调试技巧

    Visual Studio 使用调试技巧 这篇文章来源于http://damieng.com/blog/2014/02/05/8-visual-studio-debugging-tips-debug- ...

  3. Visual Studio高级调试技巧

    1. 设置软件断点,运行到目标位置启动调试器 方法①:使用汇编指令(注:x64 c++不支持嵌入汇编) _asm 方法②:编译器提供的方法 __debugbreak(); 方法③:使用windows ...

  4. 提高你开发效率的十五个Visual Studio 2010使用技巧

    提高你开发效率的十五个Visual Studio 2010使用技巧 相信做开发的没有不重视效率的.开发C#,VB的都知道,我们很依赖VS,或者说,我们很感谢VS.能够对一个IDE产生依赖,说明这个ID ...

  5. [No0000AE]在 Visual Studio 中调试 XAML 设计时异常

    在 Visual Studio 中进行 WPF, UWP, Silverlight 开发时,经常会遇到 XAML 设计器由于遭遇异常而无法正常显示设计器视图的情况.很多时候由于最终生成的项目在运行时并 ...

  6. 在Chrome+Visual Studio中调试asp.net程序很慢的问题(Firefox也有类似问题)

    在Chrome+Visual Studio中调试asp.net程序很慢的问题(Firefox也有类似问题) 今天开始起在Chrome中调试,发现问题主要出在菜单栏(layout文件)中,google了 ...

  7. 总是弹出visual studio 实时调试器 三种解决办法

    最近服务器老是弹出visual studio 实时调试器很是郁闷呀.关还关不掉.怎么解决呢 ,现像如下图所示: 下面我们一起来分析一下这种情况的原因: 弹出应用程序: Visual Studio 实时 ...

  8. Visual Studio 在调试时启用编辑功能

    Visual Studio边调试边修改 如果你在调试一个web应用程序的时候,想进行编辑,可以有如下两种方法:    方法一:在web项目的属性页里的web标签页,选中"启用编辑并继续&qu ...

  9. Visual Studio远程调试

    Visual Studio支持调试远程机器上的程序,经过简单设置后,就像调试本地代码一样方便. 第一步:将vs工具里的Remote Debugger文件夹拷贝到目标机器.大致的目录应该是:D:\Pro ...

随机推荐

  1. (数据科学学习手札44)在Keras中训练多层感知机

    一.简介 Keras是有着自主的一套前端控制语法,后端基于tensorflow和theano的深度学习框架,因为其搭建神经网络简单快捷明了的语法风格,可以帮助使用者更快捷的搭建自己的神经网络,堪称深度 ...

  2. 前端必备的Nginx学习

    由于机缘巧合,认识了一些朋友,给我介绍了搬瓦工的网站.买了一个国外的服务器,既可以FQ又拥有了一个搭载 Centos 6 的服务器.一年19.99美元,折合人民币也就130左右,一键搭建.有兴趣可以点 ...

  3. 笔记-sql语句

    笔记-sql语句 1.      sql语句基础 虽然经常使用sql语句,但没有一个整体式的文档,整理了一下. 1.1.    select foundation: select <colnum ...

  4. python中利用少量代码快速实现从类对象中抽取所需属性的一种实践

    项目中有可能会碰到这样一种场景: 根据一个id,查询得到和id对应的完整数据信息存储对象,比如书籍id到书籍详细信息,用户id到用户详细信息等,详细信息字段可能包括几十甚至上百个数据字段,真正需要返回 ...

  5. Ruby 基础教程1-9

    异常 1.异常结构      [ begin]          ...     rescue         [retry]          ...     [ensure]          . ...

  6. 「专题训练」Machine Schedule(HDU-1150)

    题意 在一个工厂,有两台机器\(A, B\)生产产品.\(A\)机器有\(n\)种工作模式(模式\(0\),模式\(1\)--模式\(n-1\)).\(B\)机器有\(m\)种工作模式(模式\(0\) ...

  7. VIN码识别:让VIN码采集so easy!

    近几年汽车后市场呈喷井式发展,在过去的半年,汽车后市场规模已高达万亿级,产业前景广阔,与此同时行业运营也受信息区域化.数据不统一的制约,让企业面临着效率低下.规模化运行困难的痛点. 在汽车配件市场中, ...

  8. JEMTER简单的测试计划

    测试计划一 1)测试网站:http://www.geneedu.cn/和http://supu01.1688.com/ 2)测试目的是该网站在负载达到20 QPS 时的响应时间. 备注: QPS : ...

  9. Java 递归 反射 正则表达式

    一 递归 1. 就是函数自身调用自身 (就是在栈内存中不断的加载同一个函数) 2. 什么时候用递归呢? 当一个功能被重复使用 而每一次使用该功能时的参数不确定 都由上次的功能元素结果来确定 简单说: ...

  10. Unity编辑器 - Undo的坑

    Unity编辑器 - Undo的坑 编辑器通过脚本中改变值,Undo.RecordObject可能会无效,应该使用: Undo.RegisterCompleteObjectUndo(Object ob ...