Tracing provides you with a snapshot of the steps your code has taken after the code has run. At times, however, you’d probably like to monitor your code while it is running. What you want is more of a CAT scan than an autopsy. The code equivalent of a CAT scan is a symbolic debugger.
When you run your code in the debugger, you can literally watch your code work, step by step. As you walk through the code, you can see the variables change values, and you can watch as objects are created and destroyed.
This section will provide a brief introduction to the most important parts of the debugger that accompanies the Visual Studio .NET Integrated Development Environment (IDE). For complete coverage of how to use the Visual Studio .NET debugger, we urge you to spend time with the documentation and to experiment freely. The debugger is one of the most powerful tools at your disposal for learning ASP.NET.
There is a Debugtoolbar available in the IDE. To make it visible, click on the View/Toolbars menu commands, then click on Debug, if it is not already checked. Table 7-3 shows the icons that appear on the Debug toolbar.
Table 7-3. Debug toolbar icons
Icon |
Debug menu equivalent |
Keyboard shortcut |
Description |
---|---|---|---|
|
Toolbar handle. Click and drag to move the toolbar to a new location. | ||
|
Start / Continue |
F5 |
Starts or continues executing the program. |
|
Break All |
Ctrl+Alt+Break |
Stops program execution at the currently executing line. |
|
Stop Debugging |
Shift+F5 |
Stops debugging. |
|
Restart |
Ctrl+Shift+F5 |
Stops the run currently being debugged and immediately begins a new run. |
|
Shows next statement. | ||
|
Step Into |
F11 |
If the current line contains a call to a method or function, this icon will single-step the debugger into that method or function. |
|
Step Over |
F10 |
If the current line contains a call to a method or function, this icon will not step into that method or function, but will go to the next line after the call. |
|
Step Out |
Shift+F11 |
If the current line is in a method or function, that method or function will complete and the debugger will stop on the line after the method or function call. |
|
Unit of debugger stepping. Possible values are
| ||
|
Hexadecimal display toggle. | ||
|
Windows |
Debug window selector. | |
|
Toolbar options. Offers options for adding and removing buttons from all toolbars (Debug, Text Editor, etc.). |
“The crux of the biscuit is the apostrophe.”
Breakpoints are at the heart of debugging. A breakpoint is an instruction to .NET to run to a specific line in your code and then to stop and wait for you to examine the current state of the application. While the execution is paused, you can:
Examine and modify values of variables and expressions
Single-step through the code
Move into and out of methods and functions, even stepping into classes written in other CLR-compliant languages
Perform any number of other debugging and analysis tasks
A breakpoint is set in the Source window (any Source window, such as page file, control file, or code-behind) by single-clicking on the gray vertical bar along the left margin of the window. A red dot will appear in the left margin and the line of code will be highlighted, as shown in Figure 7-6.
An alternative to clicking in the left margin is to select the Debug/New Breakpoint... menu command. Clicking on the File tab will bring up the dialog shown in Figure 7-7. The text boxes will already be filled in with the current location of the cursor.
The four tabs in the dialog box in Figure 7-7 correspond to the four types of breakpoints, which are described in Table 7-4.
Table 7-4. Four types of breakpoints
Type |
Description |
---|---|
Allows you to specify where, in which language, and in which method or function the break will occur. | |
Sets a breakpoint at a specific point in a source file. When you set a breakpoint by clicking in the left margin, a file breakpoint is being set. | |
Sets a breakpoint at a specified memory address. | |
Sets a breakpoint when the value of a variable changes. |
You can see all the breakpoints currently set by looking at the Breakpoint window . To display the Breakpoint window, perform any one of the following actions:
Press Ctrl+Alt+B.
Select Breakpoints from the Debug/Windows menu command.
Click on the Windows icon of the Debug toolbar and select Breakpoints.
A Breakpoint window is shown in Figure 7-8.
You can toggle a breakpoint between Enabled and Disabled by clicking on the corresponding checkbox in the Breakpoint window.
Sometimes you don’t want a breakpoint to stop execution every time the line is reached. VS.NET offers two properties that can be set to modify the behavior of a breakpoint. These properties can be set in either of two ways:
Right-click on the breakpoint glyph in the left margin and select Breakpoint properties.
Open the Breakpoint window, right-click on the desired breakpoint, and select Properties.
In either case, you will see the dialog box shown in Figure 7-9.
The fields at the top of the Breakpoint Properties dialog box will default to the location of the current breakpoint. The two buttons allow access to the Condition and Hit Count properties.
The Condition button brings up the dialog shown in Figure 7-10.
You can enter any valid expression in the edit field. This expression is evaluated when program execution reaches the breakpoint. Depending on which radio button is selected and how the Condition expression evaluates, the program execution will either pause or move on. The two radio buttons are labeled:
is true
If the Condition entered evaluates to a Boolean
true
, then the program will pause.
has changed
If the Condition entered has changed, then the program will pause. Note that on the first pass through the piece of code being debugged, the breakpoint will never pause execution because there is nothing to compare against. On the second and subsequent passes, the expression will have been initialized and the comparison will take place.
Hit count
is the number of times that spot
in the code has been executed since either the run began or the
Reset Hit Count
button was pressed. The Hit Count
button brings up the dialog shown in Figure 7-11.
Clicking on the drop-down list presents the following options:
Break always.
Break always when the hit count is equal to . . .
Break always when the hit count is a multiple of . . .
Break always when the hit count is greater than or equal to . . .
If you click on any option other than “break always” (the default), the dialog box will add an edit field for you to enter a target hit count.
Suppose this is a breakpoint set in a loop of some sort. You selected
“break when the hit count is a multiple
of” and entered 5
in the edit
field. Then the program will pause execution every fifth time it
runs.
There are several different breakpoint symbols, or glyphs, each conveying a different type of breakpoint. These glyphs appear in Table 7-5.
Table 7-5. Breakpoint icons
Icon |
Type |
Description |
---|---|---|
|
A normal, active breakpoint. If breakpoint conditions or hit count settings are met, execution will pause at this line. | |
|
Execution will not pause at this line until the breakpoint is re-enabled. | |
|
The location or condition is not valid. | |
|
The code at this line is not yet loaded, so a breakpoint can’t be set. If the code is subsequently loaded, then the breakpoint will become enabled. |
Go to the
code-behind file in the example
(either WebForm1.aspx.cs or
WebForm1.aspx.vb, depending on
your language). Place a breakpoint on the call to the Add method of
the DropDownList control’s Items collection, the
line in the Page_Load
method where the items are
added to the DropDownList. Set the Hit Count to be a multiple of 5
(break always when hit count is a multiple of 5). Then run the
program.
The breakpoint will be hit, and the program will stop execution at the line of code containing the breakpoint, which will turn yellow. The glyph in the left margin will have a yellow arrow on top of it. The VS.NET screen should look like Figure 7-12.
You can now move forward a single statement or line at a time, stepping into any methods or functions as you go, by using one of the following techniques:
Select the Debug/Step Into menu command.
Click on the Step Into icon (see Table 7-3, earlier in this chapter, for a picture of the icon).
Press F11.
You can step through the code without going through called functions or methods. That is, you can step over the calls rather than into the calls, using one of the following techniques:
Select the Debug/Step Over menu item.
Click on the Step Over icon (see Table 7-3 for a picture of the icon).
Press F10.
Finally, if you are debugging in a called method or function, you can step out of that method or function call, using one of the following techniques:
Select the Debug/Step Out menu command.
Click on the Step Out icon (see Table 7-3 for a picture of the icon).
Press Shift+F11.
To change the granularity of the stepping (i.e., step by Line, Statement, or Function), select a different value for Step By, either in the Debug Toolbar or at the Debug/Step By menu command.
Once the program is stopped, you can examine the value of objects and variables currently in scope. This is incredibly intuitive and easy. Just place the mouse cursor over the top of any variable or object in the code, wait a moment, and a little pop-up window will appear with its current value
If the cursor is hovering over a variable, the pop-up will contain the type of variable, its value (if relevant), and any other properties it may have.
If the cursor is hovering over some other object, the pop-up window will contain information relevant to its type, including its full namespace and syntax, and a descriptive line of help.
The Immediate window allows you to type almost any variable, property, or expression and immediately see its value. To open the Immediate window, do any of the following:
Press Ctrl+Alt+I.
Select Immediate from the Debug/Windows menu commands.
Click on the Windows icon of the Debug toolbar and select Immediate.
You can enter expressions for immediate execution in the Immediate
window. If you want to see the value of an expression, prepend it
with a question mark. For instance, if the breakpoint is on the line
shown in Figure 7-12, you can see the value of the
integer i
by entering:
?i
in the Immediate window and pressing Enter. Figure 7-13 shows the result of that exercise;
additionally, this figure shows the process of assigning a new value
to the variable i
and then viewing its value
again.
You can clear the contents of the Immediate window by right-clicking anywhere in the window and selecting Clear All. Close the window by clicking on the X in the upper-right corner. If you close the window and subsequently bring it back up in the same session, it will still have all the previous contents.
The Autos window shows all the variables used in the current statement and the previous statement, displayed in a hierarchical table. To open the Autos window, do any of the following:
Press Ctrl+Alt+V followed by A.
Select Autos from the Debug/Windows menu commands.
Click on the Windows icon of the Debug toolbar and select Autos.
A typical Autos window is shown in Figure 7-14.
There are columns for the name of the object, its value, and its type. A plus sign next to an object indicates that it has child objects that are not displayed while a minus sign indicates that its child objects are visible. Clicking on a plus symbol expands out the tree and shows any children, while clicking on a minus symbol contracts the tree and displays only the parent.
You can select and edit the value of any variable. The value will then display as red in the Autos window. Any changes to values take effect immediately.
The Locals window is exactly the same as the Autos window, except that it shows variables local to the current context. By default, the current context is the method or function containing the current execution location.
To open a Locals window, do any of the following:
Press Ctrl+Alt+V,L. (Press and hold Ctrl+Alt+V; release all three keys; then press L.)
Select Locals from the Debug/Windows menu commands.
Click on the Windows icon of the Debug toolbar and select Locals.
The C# This
window and the VB.NET
Me
window are exactly the same as the
Autos window, except that they show all objects pointed to by this in
C# and Managed C++ and by Me in VB.NET.
To open a This/Me window, do any of the following:
Press Ctrl+Alt+V,T/M. (Press and hold Ctrl+Alt+V; release all three keys; then press T for This or M for Me.)
Select This or Me from the Debug/Windows menu commands.
Click on the Windows icon of the Debug toolbar; select This or Me.
The Watch window is exactly the same as the Autos window, except that it shows only variables, properties, or expressions that you enter into the Name field in the window or drag from another window. The advantage of using a Watch window is that it allows you to watch objects from several different sourcewindows simultaneously. This overcomes the inability to add object types other than the specified type to any of the other debug windows.
To open a Watch window, do any of the following:
Press Ctrl+Alt+W, followed by n
, where
n
is either 1, 2, 3, or 4.
Select Watch from the Debug/Windows menu commands.
Click on the Windows icon of the Debug toolbar and select Watch.
In addition to typing in the name of the object you want to watch, you can also drag and drop variables, properties, or expressions from a Code window. Select the object in the code that you want to put in the Watch window, then drag it to the Name field in the open Watch window.
You can also drag and drop objects from any of the following windows into the Watch window:
Locals
Autos
This/Me
Disassembly
In order to drag something from one of these windows to the Watch window, both the source window and the Watch window must be open. Highlight a line in the source window, then drag it down over the Watch tab. The Watch window will come to the foreground. Continue dragging the object to an empty line in the Watch window.
The Call Stack window displays the names of the methods and functions on the call stack, as well as their parameter types and values. You can control which information is displayed in the Call Stack window by right-clicking anywhere in the window and toggling field names that appear in the lower portion of the pop-up menu. To open a Call Stack window, do any of the following:
Press Ctrl+Alt+C.
Select Call Stack from the Debug/Windows menu commands.
Click on the Windows icon of the Debug toolbar and select Call Stack.
The Threads window allows you to examine and control threads in the program you are debugging. Threads are sequences of executable instructions. Programs can be either single-threaded or multithreaded. The whole topic of threading and multiprocess programming is beyond the scope of this book.
To open a Threads window, do any of the following:
Press Ctrl+Alt+H.
Select Threads from the Debug/Windows menu commands.
Click on the Windows icon of the Debug toolbar and select Threads.
The Modules window allows you to examine the .exe and .dll files that are being used by the program being debugged. To open a Modules window, do any of the following:
Press Ctrl+Alt+U.
Select Modules from the Debug/Windows menu commands.
Click on the Windows icon of the Debug toolbar and select Modules.
A Modules window is shown in Figure 7-15.
By default, the modules are shown in the order in which they were loaded. You can re-sort the table by clicking on any of the column headers.
The Disassembly window shows the current program in assembly code. If you are debugging managed code, such as that which comes from VB.NET, C#, or Managed C++, this will correspond to Microsoft Intermediate Language (MSIL) code.
A Disassembly window is shown in Figure 7-16.
Unlike the previous windows discussed in this chapter, the Disassembly window displays as a tabbed item, as part of the main Source code window. You can set breakpoints anywhere in the window, just as for any other Source code window. To open a Disassembly window, do any of the following:
Press Ctrl+Alt+D.
Select Disassembly from the Debug/Windows menu commands.
Click on the Windows icon of the Debug toolbar and select Disassembly.
The Registers window allows you to examine the contents of the microprocessor’s registers. Values that have changed recently are displayed in red. To open a Registers window, do any of the following:
Press Ctrl+Alt+G.
Select Registers from the Debug/Windows menu commands.
Click on the Windows icon of the Debug toolbar and select Registers.
You can select which pieces of information to view by right-clicking anywhere in the Registers window and clicking on the information you would like displayed.
An application can be configured to either enable or disable debugging. This is done through the web.config file, which is described more fully in Chapter 20.
Web.config is an XML file, and as
such it must be well-formed. The file consists of sections delimited
by tags. The debugging configuration information is contained within
the
<compilation>
section, within the <system.web>
section,
which in turn is contained within the
<configuration>
section. So a typical
compilation configuration snippet will look something like Example 7-8.
Example 7-8. Debug configuration code snippet from web.config
<?xml version="1.0" encoding="utf-8" ?> <configuration> <system.web> . . . <compilation debug="true" />
Note that setting debug
to
false
improves the runtime performance of the
application.
18.118.9.197