functions such as navigating to the applicable line
of source code in the code editor or switching the
visualization to a different thread.
If you are working with an application that
uses numerous threads or tasks, or has a very
deep call stack, you may fi nd that the Parallel
Stacks call graph visualization does not fi t in the
one window. In this case you can click the icon
in the bottom - right corner of the window to
display a thumbnail view, which enables you
to easily pan around the visualization. You can
see this in Figure 39 - 17.
Parallel tasks
At the beginning of this section of the chapter we explained the new Task Parallel Library in
.NET version 4.0, which includes the Task class found in System.Threading.Tasks and the new
Parallel.For loops. The Parallel Tasks window (Debug . Windows . Parallel Tasks), shown in
Figure 39-18, assists you in debugging applications that use these new features by displaying a list
with the state of all the current tasks.
fiGure 39-17
fiGure 39-18
The application that has been paused in Figure 39-18 has created four tasks, two of which are
running and two of which are in a waiting state. You can click the flag icon to flag one or more
tasks for easier tracking.
Parallel.For, Parallel.ForEach, and the Parallel LINQ library (PLINQ)
use the System.Threading.Tasks.Task class as part of their underlying
implementation.
exceptions .
841
excePtions
Visual Studio 2010 has a sophisticated exception handler that provides you with a lot of useful
information. Figure 39-19 shows the Exception Assistant dialog that appears when an exception is
raised. In addition to providing more information, it also displays a series of actions. The Actions
list varies depending on the type of exception being thrown. In this case, the two options are to
view details of the exception or copy it to the clipboard.
fiGure 39-19
If you select the View Detail action item from
the exception, you are presented with a modal
dialog that provides a breakdown of the
exception that was raised. Figure 39-20 shows
the attributes of the exception, including the
Stack Trace, which can be viewed in full
by clicking the down arrow to the right
of the screen.
Of course, at times exceptions are used to
control the execution path in an application.
For example, some user input may not
adhere to a particular formatting constraint,
and instead of using a Regular Expression
to determine whether it matches, a parse
operation has been attempted on the string. When this fails, it raises an exception, which can easily
be trapped without stopping the entire application.
By default, all exceptions are trapped by the debugger, because they are assumed to be exceptions
to the norm that shouldn’t have happened. In special cases, such as invalid user input, it may be
important to ignore specific types of exceptions. This can be done via the Exceptions window,
accessible from the Debug menu.
fiGure 39-20
842 .
chaPter 39 uSing The debugging WindoWS
Figure 39-21 shows the Exceptions window
(Debug . Exceptions), which lists all the
exception types that exist in the .NET
Framework. Each exception has two debugging
options. The debugger can be set to break when
an exception is thrown, regardless of whether
it is handled. If the Just My Code option has
been enabled, checking the User-unhandled box
causes the debugger to break for any exception
that is not handled within a user code region.
More information on Just My Code is provided
in Chapter 41, which examines debugging attributes.
Unfortunately, the Exceptions window doesn’t pick up any custom exception types that you may
have created, but you can add them manually using the Add button in the lower-right corner of
the window. You need to ensure that you provide the full class name, including the namespace;
otherwise, the debugger will not break on handled exceptions. Clearly, unhandled exceptions will
still cause the application to crash.
customizing the exception assistant
As with a lot of the configurable parts within Visual Studio 2010, the information displayed by
the Exception Assistant is stored in an XML file (C:\Program Files\Microsoft Visual Studio
10.0\Common7\IDE\ExceptionAssistantContent\1033\DefaultContent.xml). This file can
be modified either to alter the assistant information for existing exception types or to add your
own custom exception types. If you have your own exception types, it is better practice to create
your own XML document. Simply placing it in the same directory as the DefaultContent.xml
is sufficient to register it with Visual Studio for the next time your application is debugged. An
example XML file is provided in the following code listing:
<?xml version="1.0" encoding="utf-8" ?>
<AssistantContent Version="1.0" xmlns="urn:schemas-microsoft-com:xml-msdata:
exception-assistant-content">
<ContentInfo>
<ContentName>Additional Content</ContentName>
<ContentID>urn:exception-content-microsoft-com:visual-studio-7-defaultcontent</
ContentID>
<ContentFileVersion>1.0</ContentFileVersion>
<ContentAuthor>David Gardner</ContentAuthor>
<ContentComment>My Exception Assistant Content for Visual Studio
</ContentComment>
</ContentInfo>
<Exception>
<Type>DebugApp1.myException</Type>
<Tip HelpID=”http://www.professionalvisualstudio.com/MyExceptionHelp.htm”>
<Description>Silly error, you should know better...</Description>
</Tip>
</Exception>
</AssistantContent>
fiGure 39-21
summary .
843
This example registers help information for the exception type myException. The HelpID attribute
is used to provide a hyperlink for more information about the exception. When this exception is
raised, the debugger displays the window shown in Figure 39-22.
fiGure 39-22
unwinding an exception
In Figure 39-23, there is an additional item in the Actions list
of an exception helper window, which is to enable editing.
fiGure 39-23
This is effectively the capability to unwind the execution of the
application to just before the exception was raised. In other
words, you can effectively debug your application without having to restart your debugging session.
The Enable Editing option appears only if you have configured Visual Studio to break when an
exception is thrown, as discussed earlier in this chapter. As with many of the debugging features,
both the Exception Assistant and the capability to unwind exceptions can also be disabled via the
Debugging tab of the Options window.
An alternative way to unwind the exception is to select the Unwind to This
Frame item from the right-click context menu off the Call Stack window after an
exception has been raised. This can be useful to check what the state of the appli-
cation was just before the exception was thrown. You can only unwind an excep-
tion if it is handled (that is, contained within a try . . . catch block). You should
also ensure that the debugger is set to break when the exception is thrown. You
can do this via the Debug . Exceptions window.
suMMary
This chapter has described each of the debugging windows in detail so you can optimize your
debugging experience. Although the number of windows can seem somewhat overwhelming at first,
they each perform an isolated task or provide access to a specific piece of information about the
844 .
chaPter 39 uSing The debugging WindoWS
running application. As such, you will easily learn to navigate between them, returning to those that
provide the most relevant information for you.
The following chapter provides more detail about how you can customize the debugging information.
This includes changing the information displayed in the DataTip and visualizing more complex
variable information.
40
Debugging with Breakpoints
what’s in this chaPter?
.
Using breakpoints, conditional breakpoints, and tracepoints to
pause code execution
.
Controlling the program execution during debug by stepping
through code
.
Modifying your code while it is running using the Edit and Continue
feature
Long gone are the days where debugging an application involved adding superfl uous output
statements to track down where an application was failing. Visual Studio 2010 provides a
rich interactive debugging experience that includes breakpoints, tracepoints, and the Edit
and Continue feature. This chapter covers how you can use these features to debug your
application.
breakPoints
A breakpoint is used to pause, or break, an application at a particular point of execution. An
application that has been paused is said to be in Break mode, causing a number of the Visual
Studio 2010 windows to become active. For example, the Watch window can be used to view
variable values. Figure 40-1 shows a breakpoint that has been added to the constructor of the
Customer class. The application breaks on this line if the Customer class constructor is called.
846
.
chaPter 40 debugging WiTh breAkpoinTS
fiGure 40-1
setting a breakpoint
Breakpoints can be set either through the Debug menu, using the Breakpoint item from the right-
click context menu, or by using the keyboard shortcut, F9. The Visual Studio 2010 code editor also
provides a shortcut for setting a breakpoint using a single mouse click in the margin.
An application can only be paused on a line of executing code. This means that a breakpoint set on
either a comment or a variable declaration will be repositioned to the next line of executable code
when the application is run.
simple Breakpoints
A breakpoint can be set on a line of code by placing the cursor on that line and enabling a
breakpoint using any of the following methods:
.
Selecting Toggle Breakpoint from the Debug menu.
.
Selecting Insert Breakpoint from the Breakpoint item on the right-click context menu.
.
Pressing F9.
.
Clicking once in the margin of the code window with the mouse. Figure 40-1 shows the
location of the mouse cursor immediately after a breakpoint has been set using the mouse.
Selecting Location from the Breakpoint item
on the right-click context menu for the line
of code with the breakpoint set displays the
File Breakpoint dialog, shown in Figure 40-2.
Here you can see that the breakpoint is set at
line 11 of the Customer.cs file. There is also
a character number, which provides for the
case in which multiple statements appear on a
single line.
function Breakpoints
Another type of breakpoint that can be set is a function breakpoint. The usual way to set a
breakpoint on a function is to select the function signature and either press F9 or use the mouse
to create a breakpoint. In the case of multiple overloads, this would require you to locate all the
overloads and add the appropriate breakpoints. Setting a function breakpoint enables you to set a
breakpoint on one or more functions by specifying the function name.
fiGure 40-2
Breakpoints .
847
To set a function breakpoint, select Break
at Function from the New Breakpoint item
on the Debug menu. This loads the New
Breakpoint dialog shown in Figure 40-3,
in which you can specify the name of the
function on which to break. There is a toggle
to enable IntelliSense checking for the function
name. The recommendation is to leave this
checked, because it becomes almost impossible
to set a valid breakpoint without this support.
Unfortunately, the IntelliSense option doesn’t give you true IntelliSense as you type, unlike other
debugging windows. However, if you select the name of the function in the code window before
creating the breakpoint, the name of the function is automatically inserted into the dialog.
When setting a function breakpoint, you can
specify either the exact overload you want to
set the breakpoint on or just the function name.
In Figure 40-3, the overload with a single Guid
parameter has been selected. Notice that unlike a
full method signature, which requires a parameter
name, to select a particular function overload, you
should provide only the parameter type. If you
omit the parameter information, and there are
multiple overloads, you are prompted to select the
overloads on which to place the breakpoint, as
illustrated in Figure 40-4.
address Breakpoint
Another way to set a breakpoint is via the Call Stack window. When the application is in Break
mode, the call stack shows the current list of function calls. After selecting any line in the call stack,
a breakpoint can be set in the same way as a file breakpoint, as described earlier (toggle Breakpoint
from the Debug menu, use the F9 keyboard shortcut, or use Insert Breakpoint from the context
menu). Figure 40-5 shows a short call stack with a new breakpoint set on a control event on Form1.
fiGure 40-3
fiGure 40-4
fiGure 40-5
The call stack is generated using function addresses. As such, the breakpoint that is set is an address
breakpoint. This type of breakpoint is only useful within a single debugging session, because
function addresses are likely to change when an application is modified and rebuilt.
848 .
chaPter 40 debugging WiTh breAkpoinTS
adding break conditions
Though breakpoints are useful for pausing an application at a given point to review variables and
watch application flow, if you are looking for a particular scenario it may be necessary to break only
when certain conditions are valid. Breakpoints can be tailored to search for particular conditions, to
break after a number of iterations, or even be filtered based on process or machine name.
Condition
A breakpoint condition can be specified by selecting