Visual Studio2010调试技巧

【本文地址】http://blog.joycode.com/scottgu/archives/2011/02/24/116535.joy

【大牛博客】http://blog.joycode.com/scottgu/

VS2010中的调试技巧

原文发表地址:Debugging Tips with Visual Studio 2010
原文发表时间:Wednesday, August 18, 2010 9:48 PM

这是我的博客中关于VS 2010和.NET 4发布系列的第二十六篇文章。

Today’s blog post covers some useful debugging tips that you can use with Visual Studio.  My friend Scott Cate (who has blogged dozens of great VS tips and tricks here) recently highlighted these to me as good tips that most developers using Visual Studio don’t seem to know about (even though most have been in the product for awhile).  Hopefully this post will help you discover them if you aren’t already taking advantage of them.  They are all easy to learn, and can help save you a bunch of time.

今天的博文将介绍Visual Studio中的一些实用调试技巧。这是受我朋友Scott Cate (他发表过几十篇很棒的VS技术文章) 启发。他最近告诉我,许多Visual Studio下的程序员,甚至一些很有经验的开发人员,都不知道这些技巧。希望这篇文章能帮你掌握这些技巧。它们都很简单,却能帮你节约大量的时间。

Run to Cursor (Ctrl + F10)

Often I see people debugging applications by hitting a breakpoint early in their application, and then repeatedly using F10/F11 to step through their code until they reach the actual location they really want to investigate.  In some cases they are carefully observing each statement they step over along the way (in which case using F10/F11 makes sense).  Often, though, people are just trying to quickly advance to the line of code they really care about – in which case using F10/F11 isn’t the best way to do this.

Instead, you might want to take advantage of the “run to cursor” feature that the debugger supports.  Simply position your cursor on the line in your code that you want to run the application to, and then press the Ctrl + F10 keys together.  This will run the application to that line location and then break into the debugger – saving you from having to make multiple F10/F11 keystrokes to get there.  This works even if the line of code you want to run to is in a separate method or class from the one you are currently debugging

跳到当前光标处(Ctrl+F10)

我经常看到人们为了到达目标代码位置,而在程序中早早设定了断点,然后反复地按F10/F11,一步步走到目标代码处。当程序员的确需要仔细观察每一步的状态变化时, F10/F11是合理的选择。然而多数情况下,人们只想快速到达他们真正关心的代码处,这时候F10/F11就不是最佳选择了。

这时,你应该利用“跳到当前光标处”这个功能。先把光标定位在要测的目标代码行上,再同时按Ctrl和F10,被测程序将直接跳到该行停下。你再也不用按许多次F10/F11了。即使目标代码位于独立的类或方法中,你仍然可以从当前正在检查的地方跳过去。

Conditional Breakpoints

Another common thing we often see in usability studies are cases where developers set breakpoints, run the application, try out some input, hit a breakpoint, and manually check if some condition is true before deciding to investigate further.  If the scenario doesn’t match what they are after, they press F5 to continue the app, try out some other input, and repeat the process manually.

Visual Studio’s conditional breakpoint capability provides a much, much easier way to handle this. Conditional breakpoints allow you to break in the debugger only if some specific condition that you specify is met.  They help you avoid having to manually inspect/resume your application, and can make the whole debugging process a lot less manual and tedious.

条件中断

另一种常见的情况是:开发人员设置断点,运行程序,利用不同的输入触发断点,然后在断点处手工检查是否满足某些特定的条件,从而决定是否继续调查。如果当前场景不是他们想要的,按F5继续运行程序,尝试别的输入,手动重复刚才的过程。

针对上述情况,Visual Studio提供了一个方便得多的功能——“条件中断”。只有当程序满足了开发人员预设的条件后,条件断点才会被触发,调试器中断。这将避免频繁地手工检查/恢复程序运行,大量减少调试过程中的手工和烦琐工作。

How to Enable a Conditional Breakpoint

Setting up a conditional breakpoint is really easy.  Press F9 in your code to set a breakpoint on a particular line:

如何设置条件断点

设置条件断点非常容易。在特定的行上,按F9设置断点。

Then right-click on the breakpoint “red circle” on the left of the editor and select the “Condition…” context menu:

然后右击断点–编辑窗口左侧的红点,在上下文菜单上选择“Condition…”。

This will bring up a dialog that allows you indicate that the breakpoint should only be hit if some condition is true.  For example, we could indicate that we only want to break in the debugger if the size of the local paginatedDinners list is less than 10 by writing the code expression below:
这时弹出一个对话框供你设置激活该断点所需的条件。比如:我们希望只有当局部变量paginatedDinners的尺寸小于10时,调试才中断。我们可以写出如下的表达式:

Now when I re-run the application and do a search, the debugger will only break if I perform a search that returns less than 10 dinners.  If there are more than 10 dinners then the breakpoint won’t be hit.

Hit Count Feature

Sometimes you only want to break on a condition the Nth time it is true.  For example: only break the 5th time less than 10 dinners is returned from a search.

You can enable this by right-clicking on a breakpoint and selecting the “Hit count…” menu command.

现在我再运行这个程序,实现搜索,只有返回值小于10时,程序运行才会被中断。对于大于10的值,该断点将被跳过。

记录到达断点次数

有时你希望,只有当第N次满足条件的运行到达断点时,才中断程序运行。例如:当第五次返回少于10份晚餐的查询结果时,中断程序运行。
可以通过右击断点,然后在弹出菜单上选择“Hit count…”菜单命令实现。

This will bring up a dialog that allows you to indicate that the breakpoint will only be hit the Nth time a condition is met, or every N times it is met, or every time after N occurrences:

这时系统弹出一个对话框,它允许你指定:(1)当满足条件,而且进入断点的累计次数等于N时,断点命中一次。(2)当满足条件,而且进入断点的累计次数是N的倍数时,断点命中一次。(3)当满足条件,而且进入断点的累计次数大于N时,每次命中断点。

Machine/Thread/Process Filtering

You can also right-click on a breakpoint and select the “Filter..” menu command to indicate that a breakpoint should only be hit if it occurs on a specific machine, or in a specific process, or on a specific thread.

机器/线程/进程过滤

设置如下:右击断点;在弹出菜单上选择“Filter…”菜单命令;然后指定命中断点的特定条件:在指定的机器上、或指定的进程中、或指定的线程中。

TracePoints – Custom Actions When Hitting a BreakPoint

A debugging feature that a lot of people don’t know about is the ability to use TracePoints.  A TracePoint is a breakpoint that has some custom action that triggers when the breakpoint is hit.  This feature is particularly useful when you want to observe behavior within your application without breaking into the debugger.

I’m going to use a simple Console application to demonstrate how we might be able to take advantage of TracePoints.  Below is a recursive implementation of theFibonacci sequence:

跟踪点—进入断点时的自定义操作

许多人不知道“跟踪点(TrackPoints)”这个调试功能。“跟踪点“是种特殊的断点,当它被命中时,它会触发一系列自定义操作。如果你想观察程序的行为,而又不想中断调试的时候,这个功能尤其有用。

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

In the application above, we are using Console.WriteLine() to output the final Fibonacci sequence value for a specific input.  What if we wanted to observe the Fibonacci recursive sequence in action along the way within the debugger – without actually pausing the execution of it?  TracePoints can help us easily do this.

以上程序中,我们使用Console.WriteLine() 输出针对特定输入值生成的最终斐波那契数列。如果希望在调试器里观察操作中每一次递归运算后的数列而又不实际中断程序运行,该怎么办呢?“跟踪点”可以轻松实现。

Setting up a TracePoint

You can enable a TracePoint by using F9 to set a breakpoint on a line of code, and then right-click on the breakpoint and choose the “When Hit…” context menu command:

设置跟踪点

你可以在特定的行上,按F9加跟踪点。然后
右击断点,在上下文菜单中选择“When Hit…”:

Setting up a TracePoint

You can enable a TracePoint by using F9 to set a breakpoint on a line of code, and then right-click on the breakpoint and choose the “When Hit…” context menu command:

在弹出对话框上,你可以设置命中该断点时,所触发的事件。

Above we’ve specified that we want to print a trace message anytime the breakpoint condition is met.  Notice that we’ve specified that we want to output the value of the local variable “x” as part of the message.  Local variables can be referenced using the {variableName} syntax.  There are also built-in commands (like $CALLER, $CALLSTACK, $FUNCTION, etc) that can be used to output common values within your trace messages.

Above we’ve also checked the “continue execution” checkbox at the bottom – which indicates that we do not want the application to break in the debugger.  Instead it will continue running – with the only difference being that our custom trace message will be output each time the breakpoint condition is met. 

And now when we run the application, we’ll find that our custom trace messages automatically show up in the “output” window of Visual Studio – allowing us to follow the recursive behavior of the application:

在上面例子中,我们设定一旦命中断点时就打印追踪信息。注意,我们已经把局部变量“x”的值,作为追踪信息的一部分输出。局部变量可以通过{变量名}语法输出。你还可以利用系统内置的命令($CALLER, $CALLSTACK, $FUNCTION等等),在追踪信息中输出常用的调试值。

在上例中,我们同时选中了底端的“continue execution“选项,这说明我们不希望程序中断调试状态,而是继续运行。唯一的不同是:每次断点条件满足时,我们的自定义追踪信息都将被输出。

现在当我们运行程序时,会发现自定义追踪信息自动显示在Visual Studio的“输出“窗口里。这让我们很容易看到程序的递归调用过程:

You can alternatively wire-up a custom trace listener to your application - in which case the messages you print from your TracePoints will be piped to it instead of the VS output window.

你也可以选择往应用程序中添加一个自定义追踪信息的监听器。这时追踪点的输出信息将通过它输出,而不是Visual Studio的“输出“窗口。

TracePoints – Running a Custom Macro

In a talk I gave last week in London, someone in the audience asked whether it was possible to automatically output all of the local variables when a TracePoint was hit. 

跟踪点—运行自定义的宏

上周,我在伦敦演讲时,有听众问道:当命中跟踪点时,能否自动输出所有的局部变量?

This capability isn’t built-in to Visual Studio – but can be enabled by writing a custom Macro in Visual Studio, and then wiring up a TracePoint to call the Macro when it is hit.  To enable this, open up the Macros IDE within Visual Studio (Tools->Macros->Macros IDE menu command).  Then under the MyMacros node in the project explorer, select a module or create a new one (for example: add one named “UsefulThings”).  Then paste the following VB macro code into the module and save it:

Visual Studio中并没有这样的内置功能,但我们可以写一个自定义宏来实现,然后在命中跟踪点时调用该宏。这个的实现需要先打开Visual Studio的宏编辑器(工具->宏->宏IDE菜单命令),然后在项目资源管理器的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

The above macro code loops through the current stack frame and dumps all local variables to the output window.

Using our custom DumpLocals Custom Macro

We can then take advantage of our custom “DumpLocals” macro using the simple addition application below:

上述宏代码将循环当前的堆栈,把所有的局部变量输出到“输出”窗口

使用自定义的“DumpLocals”宏

然后,我们可以在如下的一个简单程序中使用刚定制的“DumpLocals”宏了:

We’ll use F9 to set a breakpoint on the return statement within our “Add” method above.  We’ll then right-click on the breakpoint and select the “When hit” menu command:

上述代码中,我们用F9在“Add”方法的返回值处加了个断点,然后右击断点,在弹出菜单上选择“When hit”。

This will bring up the following dialog.  Unlike before where we used the “Print a message” checkbox option and manually specified the variables we wanted to output, this time we’ll instead select the “Run a macro” checkbox and point to the custom UsefulThings.DumpLocals macro we created above:

将显示如下对话框。和之前不一样, 我们不选“Print a message”选项,也不手工设定需要输出的变量;而是选择“Run a marco”复选框,并指定到我们上面创建的UsefulThings.DumpLocals宏上:

We’ll keep the “continue execution” checkbox selected so that the program will continue running even when our TracePoints are hit.

Running the Application

And now when we press F5 and run the application, we’ll see the following output show up in the Visual Studio “output” window when our Add method is invoked.  Note how the macro is automatically listing the name and value of each local variable when the TracePoint is hit:

为了使程序能在命中跟踪点后仍继续运行,我们将继续选中“continue execution”复选框。

运行程序

现在按F5运行程序,当“Add”方法被调用时,我们会在Visual Studio的“输出”窗口中看到如下结果。注意命中跟踪点时,宏会自动列出每个局部变量的名称和值:

Summary

The Visual Studio debugger is incredibly rich.  I highly recommend setting aside some time to really learn all of its features.  The above tips and tricks are but a few of the many features it provides that most people are actually unaware of.

I’ve previously blogged about other VS 2010 Debugger Improvements (including DataTip pinning, Import/Export of Breakpoints, Preserving Last Value Variables, and more).  I’ll be doing more blog posts in the future about the new VS 2010 Intellitrace and Dump File Debugging support as well.  These provide a bunch of additional cool new capabilities that can make debugging applications (including ones in production) a lot easier and more powerful.

Also make sure to check out Scott Cate’s excellent Visual Studio 2010 Tips and Tricks series to learn more about how to best take advantage of Visual Studio.  He has an absolutely awesome set of free videos and blog posts.

And also check out Jim Griesmer’s great series on Visual Studio Debugging Trips and Tricks.  He has a ton of good tips and tricks you can take advantage of.

Hope this helps,

Scott

P.S. In addition to blogging, I am also now using Twitter for quick updates and to share links. Follow me at: twitter.com/scottgu


总结

Visual Studio的调试程序功能极其丰富,我强烈建议大家花些时间去掌握它的所有功能。上述技巧是大家平时很少注意的那些功能中的一小部分。

我之前写过关于VS 2010 调试器改进的博文(包括固定数据提示窗、导入/导出断点、保留上次变量的值,等等)。以后我还会发表更多关于VS 2010的新智能提示和文件调试信息的转储支持的博文。这些技术赋予开发人员强大的调试能力,使调试程序(包括发行后的产品)变得更容易,更强大。

如果想学习更多Visual Studio知识,请参考Scott Cate的Visual Studio 2010知识与技巧系列。他发表了一系列精彩的免费视频和文章。

也可以参考 Jim Griesmer的Visual Studio调试技巧系列。他有着丰富的知识可供大家学习。

希望对大家有帮助。

Scott

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值