Condition from the Breakpoint item on the right-click
context menu for the breakpoint. This brings up the
Breakpoint Condition dialog shown in Figure 40-6,
which accepts a Boolean expression that determines
whether the breakpoint will be hit. If the expression
evaluates to false, the application continues past the
breakpoint without breaking.
In the case of Figure 40-6, which is for a breakpoint set within the Order class, the condition
specifies that the order total must be greater than 1000. As with most debugging windows, the
Condition field provides rich IntelliSense support to aid writing valid conditions. If an invalid
condition is specified, the debugger throws an appropriate error message and the application will
break the first time the breakpoint is reached.
When a condition, or a hit count, as shown in the next section, is placed on a breakpoint, the
breakpoint changes appearance. The solid red dot is replaced with a red dot with a white cross.
When you move your mouse across this dot, the tooltip provides useful information about the
breakpoint condition, as illustrated in Figure 40-7.
fiGure 40-6
fiGure 40-7
Sometimes it is more relevant to know when this condition changes status, rather than when it is
true. The Has Changed option breaks the application when the status of the condition changes.
If this option is selected, the application will not break the first time the breakpoint is hit, because
there is no previous status to compare against.
Using multiple breakpoints with complex conditions can significantly slow
down the execution of your application, so it is recommended that you remove
breakpoints that are no longer relevant in order to speed up the running of your
application.
Breakpoints .
849
Hit Count
Though it’s perhaps not as useful as breakpoint
conditions, it is also possible to break after a particular
number of iterations through a breakpoint. To do this,
select Hit Count from the Breakpoint item on the right-
click context menu. Figure 40-8 shows the Breakpoint
Hit Count dialog, which can be used to specify when
the breakpoint should be hit.
Every time the application is run, the hit count is reset
to zero, and it can be manually reset using the Reset button. The hit count is also unique to each
breakpoint. The hit count condition is one of four options:
.
Always: Disregard the hit count.
.
Is equal to: Break if the hit count is equal to the value specified.
.
Multiple of: Break if the hit count is a multiple of the value specified (as shown in
Figure 40-8).
.
Is greater than or equal to: Break if the hit count is greater than or equal to the value
specified.
Figure 40-9 shows the Breakpoints window, which provides additional information about the
status of each of the breakpoints. In this case, the breakpoint is set to break every second time. The
current hit count is 2.
fiGure 40-8
fiGure 40-9
filter
A single solution may contain multiple applications that need to be run at the same time. This is a
common scenario when building a multi-tier application. When the application is run, the debugger
can attach to all these processes, enabling them to be debugged. By default, when a breakpoint is
reached all the processes will break. This behavior can be controlled from the Debugging (General)
node in the Options window, accessible from the Options item on the Tools menu. Unchecking the
Break All Processes When One Process Breaks checkbox enables processes to be debugged individually.
If a breakpoint is set in a class library that is used by more than one process, each process will break
when it reaches that breakpoint. Because you might be interested in debugging only one of these
processes, you can place a filter on the breakpoint that limits it to the process you are interested
in. If you are debugging applications on multiple machines, it is also possible to specify a machine
name filter.
850 .
chaPter 40 debugging WiTh breAkpoinTS
In fact, filtering can be useful for a multi-threaded
application for which you want to limit the breakpoints
to a particular thread. Although the breakpoint will only
be triggered when a thread matches the filter criteria,
all threads will still be paused. Figure 40-10 shows the
Breakpoint Filter dialog and the possible filter conditions.
working with breakpoints
It’s often necessary to adjust a breakpoint, because it
might be in the wrong location or no longer relevant.
In most cases it is easiest to remove the breakpoint,
but in some cases — for example, when you have a
complex breakpoint condition — it might be necessary
to adjust the existing breakpoint.
Deleting Breakpoints
To remove a breakpoint that is no longer required, select it, either in the code editor or in the
Breakpoints window, and remove it using the Toggle Breakpoint item from the Debug menu.
Alternatively, the Delete Breakpoint item from the right-click context menu or the Delete Breakpoint
icon from the Breakpoints window toolbar will remove the breakpoint.
Disabling Breakpoints
Instead of deleting a breakpoint, simply disabling the breakpoint can be useful when you have a
breakpoint condition set or you are tracking a hit count. To disable a breakpoint, select it either
in the code editor or in the Breakpoints window, and disable it using the Disable Breakpoint
item from the right-click context menu. Alternatively, you can uncheck the checkbox against the
breakpoint in the Breakpoints window. Figure 40-11 shows how a disabled breakpoint would appear
in the code window.
fiGure 40-10
fiGure 40-11
Changing Breakpoint locations
The location of a breakpoint can be modified by selecting Location from the Breakpoint item on the
right-click context menu. Depending on what type of breakpoint has been set, the dialog shows
the location of the breakpoint as either a line and character position in a file or function, or as an
address within an assembly. If the location is either a file or function position, the breakpoint can
Breakpoints .
851
be adjusted so it is in the correct location. Address breakpoints are harder to relocate, because you
need to ensure that the new address is a valid location for a breakpoint.
labeling Breakpoints
One new feature introduced in Visual Studio 2010 is the ability to
assign a label to a breakpoint. This is particularly useful if you want
to group a set of related breakpoints together. Once labeled, you
can search for and perform a bulk action on all breakpoints with a
specific label.
To assign a label to a breakpoint, right-click the breakpoint and
choose Edit Labels. This displays the Edit Breakpoint Labels dialog,
shown in Figure 40-12, where you can attach one or more labels to
the breakpoint.
After you have labeled your breakpoints you can perform bulk actions on them by opening the
Breakpoints window (Debug . Windows . Breakpoints). This window, shown in Figure 40-13,
allows you to filter the list by typing a label in the Search box and pressing Enter. You can then
select one of the actions from the toolbar, such as Enable or Disable All Breakpoints Matching the
Current Search Criteria.
fiGure 40-12
By default, the search will be performed across all columns that are shown in the
Breakpoint window. You can limit the search to specific columns by changing the
In Column drop-down from All Visible to a specific column.
fiGure 40-13
import and export of Breakpoints
Another new debugging feature in Visual Studio 2010 is the import and export of breakpoints.
This feature allows you to back up and restore breakpoints, and share them among developers. This
functionality was previously impossible, because the location of breakpoints is stored in the binary
solution user options file (.suo), along with a whole raft of other user-specific information.
Export of breakpoints is performed from the Breakpoints window (Debug . Windows .
Breakpoints). If you only want to export a subset of your breakpoints, first filter the list by entering
a search criteria. Once the list of breakpoints that you want to export is shown, click the button
labeled Export All Breakpoints Matching the Current Search Criteria from the toolbar.
852 .
chaPter 40 debugging WiTh breAkpoinTS
Import of breakpoints can also be performed from the Breakpoints window by clicking the
appropriate button on the toolbar.
tracePoints
A tracepoint differs from a breakpoint in that it triggers an additional action when it is hit. In fact,
for purposes such as applying filters, conditions, and hit counts, a tracepoint can be thought of as a
breakpoint.
Tracepoints can be compared to using either Debug or Trace statements in your code, but tracepoints
can be dynamically set as the application is being debugged and will not affect your code.
creating a tracepoint
Tracepoints can be created from either an existing
breakpoint or the Breakpoint right-click context
menu. To create a tracepoint from an existing
breakpoint, select When Hit from the Breakpoint
right-click context menu. The resulting dialog, shown
in Figure 40-14, gives you the option of printing a
message to the console window or running a macro.
Alternatively, to create a tracepoint at a new location,
select Insert Tracepoint from the Breakpoint item on
the right-click context menu. This again loads the
dialog shown in Figure 40-14 so you can customize
the tracepoint action.
Once you set a tracepoint, the code window changes the appearance of that line of code to indicate
that a tracepoint has been set. This is shown in Figure 40-15, where the tracepoint appears with a
diamond in the margin (the diamond is red, although this can’t be seen in the figure).
fiGure 40-14
fiGure 40-15
tracepoint actions
Two types of actions can be performed when a tracepoint is hit: either print a message to the console
window or run a macro. In the dialog shown in Figure 40-14, you can indicate which action should
be run when the tracepoint is hit. If both actions are unchecked, the tracepoint will fall back to
being a breakpoint.
execution Control .
853
By default, once a tracepoint action has been indicated, the Continue Execution checkbox will be
checked so the application will not break at this point. Unchecking this option causes the application
to break at the tracepoint as if it were a breakpoint. The action defined will be performed prior to
the application breaking. The appearance of this tracepoint will be the same as that of a breakpoint,
because the visual cue indicates that the debugger will not stop at the tracepoint, rather than
indicating that there are actions associated with the tracepoint.
output Messages
As the dialog in Figure 40-14 suggests, a number of keywords can be used in conjunction with your
trace message. However, a couple of keywords are not listed by the dialog: $FILEPOS, which gives
the location of the current file, and $TICKS, which can be used as a relative time indicator.
Macros
Tracepoints can execute any Visual Studio macro, which includes macros you may have created.
Because macros can be used to modify source code, be careful which macros you execute within a
tracepoint. Modifying code while debugging an application may result in the source code being out
of sync with the running application. Visual Studio macros are discussed in Chapter 52.
execution control
After reaching a breakpoint, it is often useful to be able to step through code and review both
variable values and program execution. Visual Studio 2010 not only enables you to step through
your code, it also permits you to adjust the execution point to backtrack or even repeat operations.
The line of code that is about to be executed is highlighted and an arrow is displayed to the left, as
shown in Figure 40-16.
fiGure 40-16
stepping through code
The first step in manipulating the execution point is simply to step through code in the expected
order of execution. Three size increments can be used to step the debugger forward. It is important
to remember that when stepping through code it is actually being run, so variable values may
change as you progress through the application.
854 .
chaPter 40 debugging WiTh breAkpoinTS
stepping over (f10)
Stepping Over is fully executing the line that currently has focus and progressing to the next line in
the current code block. If the end of the code block has been reached, Stepping Over returns to the
calling code block.
stepping into (f11)
Stepping Into behaves the same as Stepping Over when the line is a simple operator, such as a
numeric operation or a cast. When the line is more complex, Stepping Into steps through all user
code. For example, in the following code snippet, pressing F10 through the TestMethod only steps
through the lines of code within TestMethod. Pressing F11 steps through TestMethod until the
MethodA call is made, and then the debugger steps through MethodA before returning to TestMethod:
c#
public void TestMethod()
{
int x = 5 + 5;
MethodA();
}
private void MethodA()
{
Console.WriteLine("Method A being executed");
}
stepping out (shift+f11)
If you step into a long method by accident, it is quite often convenient to be able to step back out
of that method without having to either step over every line in that method or setting a breakpoint
at the end of the method. Stepping Out moves the cursor out of the current method to where it was
being called. Considering the previous snippet, if you entered MethodA, pressing Shift+F11 would
immediately return the cursor to the end of TestMethod.
step filtering
One very welcome feature that was introduced with Service Pack 1 of Visual Studio 2008 is the
ability to automatically step over properties and operators. In many cases, public properties are
simply wrappers for a private member variable, and as a result there is very little to be gained from