Debugging Tips in Visual Studio 2010

Original author: Scott Guthrie
  • Transfer
This is the twenty-sixth publication in a series of publications about VS 2010 and .NET 4.

Today's publication reviews some useful debugging tips that you can apply in Visual Studio. My friend Scott Cate (who posted a dozen great VS tips and tricks on his blog ) recently drew my attention to some good tips that many developers using Visual Studio don't know about (even though many of them work with it for a long time from earlier versions).

I hope this publication helps you learn about them if you do not already know about them. All of them are easy to learn, and can save you a lot of time.

Run to Cursor (Ctrl + F10)

Often I observe people debugging applications as follows: they set a breakpoint much earlier than the place that interests them, and then they constantly use F10 / F11 to go through the code until the place that they really want to explore is reached. In some cases, they carefully examine each expression through which they pass (in such cases, using F10 / F11 makes sense). However, more often, people just try to quickly jump to the line of code that actually interests them - in such cases, using F10 / F11 is not the best way to achieve such a goal.
Instead, you can use the “run to cursor” function, which is supported by the debugger. Just place the cursor on the line of code to which you want to execute the application, and then press Ctrl + F10 together. This will lead to the execution of the application up to this line and switch to debug mode, saving time that could be spent on multiple presses of F10 / F11 in order to get here. This works even in cases where the code you want to get into is in a separate method or class in relation to the place that you are currently debugging.

Conditional Breakpoints

Another common situation that we often observe is when developers set breakpoints, execute the application, check for a specific input, get to the breakpoint, and then manually check if the condition is true before deciding whether to proceed to further consideration in debug mode. If the script does not match what they do next, they press F5 to continue the application, check some other input, and repeat the process manually.

Visual Studio's ability to set conditional breakpoints provides a much, much easier way to achieve this. Conditional breakpoints allow you to switch to debug mode only if any specific condition that has been assigned is reached. Conditional breakpoints help you to avoid manual study of the code with its further execution, and can also make the whole debugging process not requiring your manual intervention and save you from boring work.

How to enable a Conditional Breakpoint

Setting up conditional breakpoints is simple in reality. Press in F9 code to set a point on a specific line (approx. per. you can also set a breakpoint by clicking on the left border of the editor window exactly at the line level where you want to set a breakpoint ):

image

Then, right-click on the red circle of the breakpoint to the left of the editor window and select the Condition ... context menu ( “Condition ...”):

image

This will bring up a dialog box that allows you to specify that the breakpoint should only fire if a certain condition is true. For example, we can indicate that you need to go into debugging if the size of the local paginatedDinners list is less than 10 by writing the following expression below:

image

Now, when I restart the application and perform a search, the debugger will be enabled only if I perform a search that returns less than 10 lunches. If there are more than 10 dinners, then the breakpoint will not be reached.

Hit Count Function

Sometimes you need the debugger to stop only if the condition is true N times.
For example, stop only if already 5 times the search returned less than 10 dinners.

You can enable this behavior by right-clicking on the breakpoint and selecting the menu item “Hit count ...” (“Number of hits ...”).

image

This will bring up a dialog box that allows you to specify that the breakpoint should only be reached N times when the condition is reached or every N times when it is reached, or every time after N occurrences:

image

Filtering by Machine / Thread / Process ( Machine Name / Thread / Process)
You can also right-click on a breakpoint and select “Filter ...” from the context menu to indicate that a breakpoint should be reached if the debugging process occurs on a specific machine or in a specific process or in a definition ennoy stream.

TracePoints - user events when they hit a breakpoint

A debugger feature that many people don’t know about is the ability to use TracePoints (TracePoints). A trace point is a breakpoint upon reaching which a user event is triggered. This functionality is especially useful when you need to track behavior in your application without stopping in debugging.

I am using a simple Console application to demonstrate how we could use Trace Points. The following is a recursive implementation of the Fibonacci series :

image

In the application above, we use Console.WriteLine () to display the final value of the series for a specific range value. What if we wanted to track the recursive sequence of the Fibonacci series in action at the same time as debugging - without actually stopping or stopping it? Trace points can help us do this easily.

Setting a trace point (TracePoint)

You can enable trace points by using the F9 key to set a breakpoint in the line of code and then right-clicking on the breakpoint and selecting “When Hit ...” from the context menu menu:

image

This will bring up a dialog box that allows you to specify what should happen when a breakpoint is reached:

image

We indicated above that we want to display a trace message every time a breakpoint condition is reached. Notice that we indicated 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 (such as $ CALLER, $ CALLSTACK, $ FUNCTION, etc.) that can be used to output general values ​​to your trace messages.

Above, we also checked the box next to “continue execution” at the bottom, which indicates that we do not need the application to stop in the debugger. On the contrary, it will continue to be executed only with the difference that our custom trace message will be displayed every time the conditions of the breakpoint are reached.

And now, when we run the application, we will see that our custom trace message is automatically displayed in the Visual Studio "output" window, allowing us to monitor the recursive behavior of the application:

image

As an alternative to the method described above, you can create a custom trace listener for of your application, in this case, messages generated at the trace points will be redirected to it instead of the VS output window.

TracePoints - executing a custom macro

In a conversation I had last week in London, someone in the audience asked if it was possible to automatically display local variables when a TracePoint was reached.

This feature is not built into Visual Studio, but can be enabled using a custom macro and then setting up the Trace Point to call the macro when that point is reached. To do this, open the integrated environment for macros inside Visual Studio (Tools-> Macros-> Macros IDE menu command). Next, under the MyMacros node in the project browser, select the module or create a new one (for example: with the name “UsefulThings”). After that, insert the following macro code on VB into the module and save it:

VB: C # The macro code above cycles through the current stack and displays all the variables in the output window. Using our custom DumpLocals macro
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

* This source code was highlighted with Source Code Highlighter.




void DumpLocals() {
    EnvDTE.OutputWindow outputWindow;
    outputWindow = DTE.Windows.Item[EnvDTE.Constants.vsWindowKindOutput].Object;
    EnvDTE.StackFrame currentStackFrame;
    currentStackFrame = DTE.Debugger.CurrentStackFrame;
    outputWindow.ActivePane.OutputString(("*Dumping Local Variables*" + "\r\n"));
    foreach (EnvDTE.Expression exp in currentStackFrame.Locals) {
      outputWindow.ActivePane.OutputString((exp.Name + (" = "
              + (exp.Value.ToString() + "\r\n"))));
    }
  }

* This source code was highlighted with Source Code Highlighter.







Then we can use our custom “DumpLocals” macro as a simple additional application, which is shown below:

image

We will use the F9 key to set a breakpoint on the return expression in our
“Add” method above. Then right-click on the breakpoint and select the “When hit” command from the context menu:

image

This will bring up the following dialog box. Unlike the previous code, where we used the “Print a message” flag and manually defined the variables that we want to output, this time we will select the “Run a macro” flag instead and indicate the UsefulThings.DumpLocals macro that we created above:

image

We will leave the “continue execution” checkbox selected so that the program continues to run even after reaching the trace point.

Launching the application

And now, when we press the F5 key and launch the application, we will see the following output in the “output” window of Visual Studio when our Add method is launched. Notice how the macro automatically displays the name and value of each variable in the list when it reaches the trace point:

image

Summary

Visual Studio debugger is incredibly rich in features. I highly recommend that you set aside some time to truly explore all of its possibilities. The tips and tricks described above represent only a small fraction of its capabilities that people are not really aware of.

Last time I wrote on a blog about other improvements in the VS 2010 debugger (including outputting hints on the type of data (DataTip), Import / Export breakpoints, Saving the latest values ​​of variables, and much more). I will continue to write on the blog about new features of VS 2010: Intellitrace, as well as support for Debugging a dump file. Publications I will describe a bunch of additional cool new features that can make debugging applications even easier.

Also, be sure to check out the excellent Scott Kat series Visual Studio 2010 Tips and Tricks to find out how best to use Visual Studio. He has an unmatched set of free videos and blog posts.

Hope this helps,

Scott

PS In addition to blog posts, I also now use twitter for quick updates and link exchanges. Follow me: twitter.com/scottgu

Also popular now: