Debugging
The most important task in development is to debug non-trivial solutions. The VS IDE offers a large number of tools to assist you in this task. Depending on the complexity of the solution, debugging can be quite difficult and time consuming. One of the best features of the VS IDE is that we can interact with it during debugging sessions.
Selecting the Debug menu reveals the available tools and options. As we can see, most of the commands and windows are familiar from Classic VB. During the debugging process, and while in break mode, additional tools become available as shown in Figure 24-10. Although a detailed walkthrough is beyond the scope of this chapter, we focus on the most important new and updated debugging tools that the VS IDE provides. See the Chapter 16, "VBA Debugging," for a more detailed discussion of the debugging process.
Figure 24-10 Debugging tools available in break mode
Set Keyboard Shortcuts
Before we start to explore the many tools for debugging, we customize our keyboard shortcuts. Select Tools > Options... from the menu to display the Options dialog. In the Options dialog tree view, select the Keyboard section under Environment, as shown in Figure 24-11.
Figure 24-11 Keyboard shortcuts
This section allows us to set the mapping scheme for keyboard shortcuts. Changing the mapping scheme to Visual Basic 6.0 provides access to all the well-known VB6 keyboard shortcuts in the VS IDE. This change is global, meaning it will be applied for all VB.NET solutions in the VS IDE. The keyboard shortcuts mentioned in the rest of this chapter assume this setting has been made in your environment.
Enable Unmanaged Code Debugging
If we do a lot of interoperability development, that is, calls to COM objects, the option Enable unmanaged code debugging gives us the possibility to debug the native code. Select Project > [Solution Name] Properties... from the menu to display the Properties window; then select the Debug tab and check this option.
The Exception Assistant
Whenever a runtime exception is thrown, the Exception Assistant highlights the line of code that caused the exception and displays a dialog with suggestions on how to solve the problem. Figure 24-12 shows the Exception Assistant in action.
Figure 24-12 The Exception Assistant
The Exception Assistant attempts to provide context-sensitive help related to the exception, and it allows the developer to perform certain actions, such as viewing details of the exception and copying exception information to the Clipboard. For COM exceptions, however, the information provided by the Exception Assistant is of limited value.
We can provide troubleshooting tips for our own exception types by creating an XML file containing the information in the correct ExceptionAssistantContent directory under C:\Program Files\Microsoft Visual Studio 9.0\Common7\IDE\ExceptionAssistantContent.
The Object Browser (F2)
The Object Browser is one of the most valuable development resources. The VS IDE ships with a modern Object Browser that can be customized by selecting the Object Browser Settings icon on its toolbar, as shown in Figure 24-13. We can also add components to the Custom Component Set Browsing scope by selecting the Edit Custom Component Set button directly to the right of the Browse drop-down in the Object Browser toolbar.
Figure 24-13 The Object Browser
The Browse drop-down is used to limit the scope of items displayed in the Object Browser. One of the selections available is to browse My Solution, as shown in Figure 24-13. This option allows us to browse the objects in our solution as well as any outside namespaces the solution references.
The Error List Window (Ctrl+W Ctrl+E)
The Error List window shows errors, warnings and other messages that result from attempting to compile the active project. It detects most common syntax and deployment errors. Figure 24-14 shows an example Error List window displaying some errors. Double-clicking on an item in the list takes you to the module and line of code it refers to.
Figure 24-14 The Error List Window
The keyboard shortcut to display the Error List window requires two steps, Ctrl+W followed by Ctrl+E. It may feel a bit odd to use two instructions to access a feature, but this reflects how many features the VS IDE contains.
The Command Window (Ctrl+Alt+A) and Immediate Window (Ctrl+G)
The Command window and Immediate window overlap each other to some degree, but they actually have two different tasks to accomplish. The Command window allows you to execute VS IDE commands instead of going through the menus and toolbars. It can also execute commands to open other windows.
Suppose we have started a debugging session and we are running in break mode. If we enter the command shown in Listing 24-22 into the Command window the variable bExport will be added to the Watch window.
Listing 24-22. Add a Watch Using the Command Window
>Debug.AddWatch bExport
If we want to see all the command aliases, or command shortcuts, defined by the VS IDE, we can run the command >Alias in the Command window to produce a list.
The Immediate window in the VS IDE behaves much like its counterpart in Classic VB. We can assign variables, run procedures, and invoke methods in standard VB.NET syntax in the Immediate window.
The Output Window (Ctrl+Alt+O)
The Output window displays compilation results and the text output from several tools such as Debug and Trace. The Show output from: drop-down in the toolbar allows you to show the output from either the debug or the build process. It is also possible to save the output to a text file by clicking anywhere inside the Output window and then using the keyboard shortcut Ctrl+S.
Break Points (Ctrl+Alt+B)
To insert a new break point, use the keyboard shortcut Ctrl+B. Compared with its older sibling in Classic VB, the break points feature has been improved significantly in VS.NET. First, VS.NET provides a Breakpoints window that displays the location and settings for all break points in the solution, as shown in Figure 24-15.
Figure 24-15 The Breakpoints Window
Second, we can set conditions for a break point by right-clicking on that break point and selecting Condition... from the shortcut menu. In Figure 24-15 we set a condition for the first break point. When the break point is reached, this condition is evaluated to determine whether it is true or false. If the condition is true the break point is triggered; otherwise, the break point is skipped.
Third, we can add a hit count for a break point by right-clicking on that break point and selecting Hit Count... from the shortcut menu. This provides us with an additional parameter to control whether code execution should stop at break points. Figure 24-16 shows us defining a hit count for our first break point in the Breakpoint Hit Count dialog.
Figure 24-16 Defining a break point hit count
The Call Stack (Ctrl+L)
The Call Stack window displays the method calls that are currently on the stack. It is a useful debugging tool because it allows you to see the specific execution path that led to the current position in your code.
The Quick Watch and Watch Windows
Once our code is in break mode we have access to the Quick Watch and Watch windows. The Watch window, accessed by selecting the Debug > Windows > Watch menu while in break mode, provides four different Watch tabs. It is easy to add watches. You can drag and drop an object or expression onto the Watch window or select the object or expression in the code editor, right-click on it, and choose Add Watch from the shortcut menu. To delete a watch, select it in the Watch window, right-click on it, and choose Delete Watch from the shortcut menu. You can add as many different watches as you want. To access one of the Watch windows during a debugging session, press Ctrl+Alt+W followed by a digit between 1 and 4.
Quick Watch works the same way as the Watch window except that it can only handle one watch variable at the time.
Exceptions (Ctrl+Alt+E)
The Exceptions dialog is an advanced debugging tool that allows us to specify what types of exceptions we want VS.NET to throw during debugging. The debugger stops whenever the selected type of exception occurs. Figure 24-17 shows this dialog.
Figure 24-17 The Exception dialog
The Thrown option causes the debugger to break unconditionally when the specified exception type occurs. If we check the Thrown option for the Common Language Runtime Exceptions, we ensure that when a Common Language Runtime exception is thrown it breaks into the debugger, overriding any custom SEH we may have defined. The User-unhandled option causes the debugger to stop for the specified exception type only if no error handler is active when the exception occurs.
We can also configure specific exception types below the top-level namespaces by clicking on the plus sign (+) to the left of a namespace. This expands the namespace node to show all exceptions within the namespace that can be configured.
Conditional Compilation Constants
Chapter 16 introduced the concept of conditional compilation constants, so in this section we only cover conditional compilation topics that are specific to the .NET platform.
VB.NET provides several predefined conditional compilation constants, including the Boolean constant DEBUG. When DEBUG is set to true we have a debug build, and when it is set to false we have a release build. When compiling a release build we do not need to manually remove any debugging information. VS.NET handles this automatically when the DEBUG constant is set to false. Debugging information is also ignored when running a release build in the VS IDE. To compile a release build we need to use the Configuration Manager. Verify that the Configuration Manager is available in the following manner:
- Select the Tools > Options... menu from the VS IDE.
- Select Projects and Solutions from the tree view in the Options dialog.
- Check the Show advanced build configurations check box.
- Click the OK button to close the Options dialog.
We can then access the Configuration Manager by selecting Build > Configuration Manager... from the VS IDE menu, as shown in Figure 24-18. By changing the configuration we can switch between debug and the release builds. We can also use the Configuration Manager to specify which platform to target.
Figure 24-18 The Configuration Manager
We can execute code conditionally based on the value of the DEBUG constant as shown in Listing 24-23.
Listing 24-23. Using DEBUG in Code
#If DEBUG then 'Do some evaluation. #End If
Using Assertions
The Debug.Assert method is used exactly the same way in the VS IDE as it is in Classic VB. Chapter 16 already covered the use of this method, so we do not discuss it further here.