Debugging

   


Instrument and debug a Windows service, a serviced component, a .NET Remoting object, and an XML Web service.

  • Configure the debugging environment.

  • Use interactive debugging.

Log test results.

  • Resolve errors and rework code.

  • Control debugging in the Web.config file.

  • Use SOAP extensions for debugging.

Debugging is the process of finding the causes of errors in a program, locating the lines of code that are causing those errors, and fixing those errors.

NOTE

Runtime Errors and Compile-time Errors Compile-time errors are produced when a program does not comply with the syntax of the programming language. These errors are trivial to find and are generally pointed out by compilers themselves . Runtime errors occur in those programs that are compiled successfully but do not behave as expected. The process of testing and debugging applies to runtime errors only. Testing reveals these errors, and debugging repairs them.


Without tools, the process of debugging can be very time-consuming and tedious . Thankfully, Visual Studio .NET comes loaded with a large set of tools and features to help you with various debugging tasks . Some of these features include

  • Support for the cross-language debugging of Visual Basic .NET, Visual Basic .NET, Visual C++ .NET, Managed Extensions for C++, script, and SQL.

  • Support for debugging both managed and unmanaged applications.

  • Ability to attach a debugger to a running program outside the Visual Studio .NET environment on a local or remote machine.

  • Support for end-to-end debugging for distributed applications.

Configuring the Debugging Environment

When starting a program from Visual Studio .NET for debugging, you should ensure that the program is started in the Debug configuration. In addition to this, to enable debugging in the ASP.NET Web application or a Web service, make sure that the debug attribute of the <compilation> element in the web.config file is set to true .

 <compilation     defaultLanguage="vb"     debug="true"/> 

WARNING

Applications Will Run Significantly Slower in Debug Mode When debugging is enabled for an application, the compiler will include extra debugging information in the page, creating a large output file that executes slowly.


Also, in ASP.NET Web applications and Web services ensure that the Enable ASP.NET Debugging property is set to True . The Enable ASP.NET Debugging property is found in the Configuration Properties, Debugging option in the project's Property Pages dialog box.

NOTE

Debugging from Visual Studio .NET When you run an application from Visual Studio .NET, it automatically attaches a debugger to the process in which your application is running. In the case of ASP.NET Web applications and Web services, the debugger is also attached to the ASP.NET worker process ( aspnet_wp.exe ) if the Enable ASP.NET Debugging property is set to True in the project's Property Pages dialog box.


Setting Breakpoints and Stepping Through Program Execution

A common technique for debugging is the step-by-step execution of a program, sometimes called stepping . This systematic execution allows you to track the flow of logic to ensure that the program is following the path of execution that you expect it to follow. If there is a difference, you can immediately identify the location of a problem.

Stepping also gives you an opportunity to monitor its state before and after a statement is executed. This includes checking the values in variables , the records in a database, and other changes in environment. Visual Studio .NET provides you with tools to make these tasks convenient .

The Debug menu provides three options for step execution of a program, as listed in Table 9.6. The Keyboard shortcuts listed in the table correspond to the Visual Basic settings of the Visual Studio IDE. If you have personalized the keyboard scheme either through the Tools, Options, Environment, Keyboard menu or through the Visual Studio .NET Start Page, you might have a different keyboard mapping. You can check out the keyboard mappings available for your customization through Visual Studio .NET's context sensitive help.

Table 9.6. Debug Options for Step-by-Step Execution

Debug Menu Item

Keyboard Shortcut

Purpose

Step Into

F8

Executes the code in step mode; if a method call is encountered , the program execution steps into the code of the function and executes the method in step mode.

Step Over

Shift+F8

Use this key when a method call is encountered and you do not want to step into the method code. When this key is pressed, the debugger will execute an entire method without any step-by-step execution (interruption) and then step to the next statement after the method call.

Step Out

Ctrl+Shift+F8

Use this key inside a method call to execute the rest of the method without stepping and resume step execution mode when the control reaches back to the calling method.

Breakpoints are markers in the code that signal the debugger to pause execution as soon as it encounters one. Once the debugger pauses at a breakpoint, you can take your time to analyze variables, data records, and other settings in the environment to determine the state of the program. You can choose to execute the program in step mode from this point on.

If you have placed a breakpoint in the Click event handler of a button, the program will be paused when you click the button and the execution reaches the point where you have marked the breakpoint. You can now step through the execution for the rest of the event handler. Once the handler code is over, control will be transferred back to the form under execution. This time, if the user clicks another button and if you don't have a breakpoint set in its event handler, the program is no longer under step execution. Be sure to insert breakpoints wherever you want execution to pause for debugging.

STEP BY STEP

9.7 Setting Breakpoints and Performing Step-By-Step Execution

  1. Add a new Visual Basic .NET Windows application named StepByStep9-7 to the solution.

  2. In the Solution Explorer window, right-click Form1.vb and select Delete from the context menu.

  3. Using the Solution Explorer window, drag the FactorialCalculator.vb form from the StepByStep9-1 project to the new project. While dragging, hold down the Ctrl key so that the form is copied to the current project instead of being moved. Change the Text property of the form to Factorial Calculator 9-7 .

  4. Set the form as the startup form for the project and set the project as the startup project for the solution.

  5. Add the following method to the class:

     Private Function Factorial(_  ByVal intNumber As Integer) As Integer     Dim intFac As Integer = 1     Dim i As Integer     For i = 2 To intNumber         intFac = intFac * i     Next     Factorial = intFac End Function 
  6. Modify the Click event handler of btnCalculate so that it looks like this:

     Private Sub btnCalculate_Click(_  ByVal sender As System.Object, _  ByVal e As System.EventArgs) _  Handles btnCalculate.Click     Dim intNumber, intFactorial As Integer     Try         intNumber = Convert.ToInt32(txtNumber.Text)         intFactorial = Factorial(intNumber)         txtFactorial.Text = intFactorial.ToString()     Catch ex As Exception         Debug.WriteLine(ex.Message)     End Try End Sub 
  7. In the Click event handler, right-click the beginning of the line that makes the call to the Factorial method and select Insert Breakpoint from the context menu. The line of code is highlighted with red, and a red dot appears in the left margin, as shown in Figure 9.15. You can also create a breakpoint by clicking in the left margin next to the line where you'd like the breakpoint to be set.

    Figure 9.15. You can enter step-by-step execution mode by setting a breakpoint in a program.

  8. Set the project StepByStep9-7 as the startup project for the solution, and set the form as the startup object for the project.

  9. Run the solution. Enter a value in the text box and click the Calculate button. Execution pauses at the location where you have marked the breakpoint. You should see an arrow on the left margins of the code as shown in Figure 9.16. This arrow indicates the next statement to be executed.

    Figure 9.16. When the breakpoint is reached during execution, the execution of the program pauses at that point.

    NOTE

    The Disassembly Window Shows Assembly Code Instead of MSIL Although Visual Basic .NET programs are compiled to Microsoft Intermediate Language (MSIL), they are just-in-time compiled to native assembly code only at the time of their first execution. This means that the executing code is never in IL; it is always in native code. Thus, you will always see native code instead of IL in the Disassembly window.

  10. Press F8 to step into the code of Factorial function. Hover the mouse pointer over various variables in the Factorial function. You will see the current values of the variables.

  11. Select Debug, Windows, Breakpoints. The Breakpoints window opens, as shown in Figure 9.17. Right-click the breakpoint listed in the window and select Go to Disassembly. The Diassembler opens, showing you the object code of the program, along with the disassembled source code.

    Figure 9.17. The Breakpoints window gives you convenient access to all breakpoint- related tasks in one place.

  12. Close the Disassembly window. From the Debug menu, select Step Out to automatically execute the rest of the factorial function and start the step mode again in the event handler at the next statement. Step through the execution until you see the form again.

  13. Select Stop Debugging from the Debug menu. This ends the debugging session and terminates the application.

  14. In the Code view, right-click the statement in which you have set the breakpoint and select Disable Breakpoint from the context menu.

NOTE

Disabling Versus Removing a Breakpoint When you remove a breakpoint, you lose all information related to it. Alternatively, you can choose to disable a breakpoint. Disabling a breakpoint does not pause the program at that point, but Visual Basic .NET will still remember the breakpoint settings. At any time, you can select Enable Breakpoint to reactivate the breakpoint.


In addition to using the method described in Step By Step 9.7, you can set a breakpoint by choosing New Breakpoint from the Debug menu or from the context menu in a module. The New Breakpoint dialog box (see Figure 9.18) has four tabs that allow you to set a breakpoint in a function, in a file, at an address in the object code, or when the data value (that is, the value of a variable) changes.

Figure 9.18. The New Breakpoint dialog box allows you to create a new breakpoint.

Clicking the Condition button opens the Breakpoint Condition dialog box, as shown in Figure 9.19. The Breakpoint Condition dialog box allows you to set a breakpoint based on the runtime value of an expression.

Figure 9.19. The Breakpoint Condition dialog box allows you to set a breakpoint that is based on the value of an expression at runtime.

Clicking the Hit Count button opens the Breakpoint Hit Count dialog box, as shown in Figure 9.20. This dialog box enables you to break the program execution only if the specified breakpoint has been hit a given number of times. This can be especially helpful if you have a breakpoint inside a lengthy loop and you want to step-execute the program only near the end of the loop.

Figure 9.20. The Breakpoint Hit Count dialog box enables you to break the program execution only if the specified breakpoint has been hit a given number of times.

Analyzing Program State to Resolve Errors

When you break the execution of a program, the program is stuck at a particular state in its execution cycle. You can use various debugging tools to analyze the values of variables, the results of expressions, or the path of execution to help identify the cause of the error that you are debugging.

Step by Step 9.8 demonstrates various Visual Basic .NET debugging tools, such as the Watch, Autos, Locals, Me, Immediate, Output, and the Call Stack windows.

STEP BY STEP

9.8 Analyzing Program State to Resolve Errors

  1. Add a new Visual Basic .NET Windows application named StepByStep9-8 to the solution.

  2. In Solution Explorer, copy the FactorialCalculator.vb form from the StepByStep9-7 project to the current project. Change the Text property of the form to Factorial Calculator 9-8 . Delete the default Form1.vb .

  3. Change the code in the Factorial method to the following (note that I have introduced a logical error that I will later "discover" through debugging):

     Private Function Factorial(_  ByVal intNumber As Integer) As Integer     Dim intFac As Integer = 1     Dim i As Integer     For i = 2 To intNumber + 1         intFac = intFac * i     Next     Factorial = intFac End Function 
  4. Set the project StepByStep9-8 as the startup project and set the form as the startup object.

  5. Run the program. Enter the value 5 in the text box and click the Calculate button. You should see that the result is not correct; this program needs to be debugged .

  6. Set a breakpoint in the Click event handler of btnCalculate at the line where a call to the Factorial function is being made. Execute the program, enter the value 5 again, and click the Calculate button.

  7. Press the F8 key to step into the Factorial function. Select Debug, Windows, Watch, Watch1 to add a watch window. Similarly, select Debug, Windows and add the Locals, Autos, Me, Immediate, and Call Stack windows. Pin down the windows so that they always remain in view and are easy to watch as you step through the program.

  8. Look at the Call Stack window (see Figure 9.21). It shows the method call stack, giving you information about the path the code has taken to reach its current point of execution. The currently executing method is at the top of the stack, with an arrow pointing to it. When this method quits, the next entry in the stack will be the method receiving the control of execution.

    Figure 9.21. The Call Stack window enables you to view the names of methods on the call stack, parameter types and their values.

  9. Look at the Me window, shown in Figure 9.22. In the Me window, you can examine the members associated with the current object (the Factorial form). You can scroll down to find the txtNumber object. You can change the values of these objects here. At this point, you don't need to change any values.

    Figure 9.22. The Me window enables you to examine the members associated with the current object.

  10. Activate the Autos window, which is shown in Figure 9.23. The Autos window displays the variables used in the current statement and the previous statement. The debugger determines this information for you automatically; that is why the name of this window is Autos.

    Figure 9.23. The Autos window displays the variables used in the current statement and the previous statement.

  11. Invoke the Locals window, which is shown in Figure 9.24. The Locals window displays the variables that are local to the current context (that is, the current method under execution) with their current values. Figure 9.24 shows the local variables in the Factorial() method.

    Figure 9.24. The Locals window displays the variables local to the current method under execution.

  12. Activate the Immediate window. Type ?intNumber and click Enter. Visual Studio .NET immediately evaluates and displays the current value of this variable in the next line. Now type the expression ?Factorial(intNumber) . The Immediate window calls the Factorial function for the given value and prints the result. The Immediate window can therefore be used to print values of variables and expressions while you are debugging a program.

  13. Invoke the Watch1 window. The Watch window enables you to evaluate variables and expressions. Select the variable intFac from the code and drag and drop it in the Watch1 window. You can also double-click the next available row and add a variable to it. Add the variables i and intNumber to the Watch1 window, as shown in Figure 9.26.

    Figure 9.26. The Watch window enables you to evaluate variables and expressions.

  14. Step through the execution of the program by pressing the F11 key. Keep observing the way values change in the Watch1 (or Autos or Locals) window. After a few steps, the method terminates. Note that the program executed only until the value of i was 4 and that the loop was not iterated back when the value of i was 5 . This causes the incorrect output in the program.

    EXAM TIP

    No Break-Edit-Continue Capability In Visual Basic 6.0, you could edit the code of a running program, and the new code would be used immediately without a restart. This Break-Edit-Continue capability is not present in Visual Basic .NET.

  15. Attempt to change the For statement to run from 2 to intNumber . Press F8 to step through the program. You'll receive a warning on the status bar, as shown in Figure 9.27. Stop the propgram, edit the code, and restart it. The code is recompiled, and the program restarts.

    Figure 9.27. By default, Visual Basic .NET does not let you edit the code of a running application.

  16. Enter the value 5 in the text box and click the Calculate button. The program breaks into the debugger again because the breakpoint is still active. Step through the program and watch the values of the variables. The loop is executed the correct number of times, and you get the correct factorial value.

NOTE

Two Modes of the Command Window The Command window has two modes: the Command mode and the Immediate mode. When you invoke the Command window by selecting View, Other Windows, Command Window, it is invoked in Command mode. In Command mode, the window can be used to issue commands such as Edit to edit the text in the file. You can use regular expressions with the Edit command to make editing operations extremely quick and effective. The Command window shows a > prompt (see Figure 9.25).

Figure 9.25. The Command window can appear in two modes: the command mode and the immediate mode.

On the other hand, when you invoke the Command window by selecting Debug, Window, Immediate, you can use it to evaluate expressions in the currently debugged program. The Immediate mode does not show any prompt. You can switch from Immediate mode to Command mode by typing >cmd , and you can switch from Command mode to Immediate mode by typing the immed command.


Debugging When an Exception Occurs

You can control the way the debugger behaves when it encounters a line of code that throws an exception. You can control this behavior through the Exceptions dialog box, shown in Figure 9.28, which is invoked via the Debug, Exceptions menu option. The Exceptions dialog box allows you to control the debugger's behavior for each type of exception defined in the system. In fact, if you have defined your own exceptions, you can add them to this dialog box.

Figure 9.28. The Exceptions dialog box allows you to control the debugger's behavior for system and custom defined exceptions.

There are two levels at which you can control the behavior of the debugger when it encounters exceptions:

  • If the exception is thrown You can instruct the debugger to either continue or break the execution of the program when an exception is thrown. The default setting for common language runtime exceptions is to continue the execution, possibly in anticipation that there will be an exception handler.

  • If the exception is not handled If the program that you are debugging fails to handle an exception, you can instruct the debugger to either ignore it and continue or to break the execution of the program. The default setting for common language runtime exceptions is to break the execution, warning the programmer of a possible problematic situation.

NOTE

Support for Cross-Language Debugging Visual Studio .NET supports debugging projects that contain code written in several managed languages. The debugger can transparently step in and step out from one language to another, making the debugging process smooth for you as a developer. Visual Studio .NET also extends this support to unmanaged languages, but with minor limitations.


GUIDED PRACTICE EXERCISE 9.2

The Factorial Calculator program created in Step by Step 9.4 throws exceptions of type System.FormatException and System.OverflowException when users are not careful about the numbers they enter.

The later versions of this program (created in Step by Steps 9.7 and 9.8) catch the exception to prevent users from complaining about the annoying exception messages.

The goal of this exercise is to configure the debugger in Step by Step 9.8 so that when the reported exception occurs, you get an opportunity to analyze the program.

How would you configure the debugger?

You should try doing this on your own first. If you get stuck, or if you'd like to see one possible solution, follow these steps:

  1. Open the Windows application project StepByStep9-8 .

  2. Activate the Exceptions dialog box by selecting Debug, Exceptions.

  3. In the Exceptions dialog box, click the Find button. Enter System.FormatException and click the OK button. You are quickly taken to the desired exception in the exception tree view.

  4. Select Break into the Debugger from the When the Exception Is Thrown group box.

  5. Repeat steps 3 and 4 for System.OverFlowException .

  6. Run the project and enter a nonnumeric value in the text box. This causes a System.FormatException error, and the debugger prompts you to either break or continue the execution, rather than automatically throwing execution into the Catch block. Select Break. You can now note the values of various variables at this stage either by hovering the mouse pointer over them or by adding the variables to the Watch window. On the next run of the program, enter a very large value. This causes a System.OverFlowException to be thrown. Select Break when prompted by the debugger, and then analyze the values of various variables.

REVIEW BREAK

  • Debugging is the process of finding the causes of errors in a program, locating the lines of code that are causing the error, and fixing the errors.

  • The three options available while performing step-by-step execution are Step Into, Step Over, and Step Out.

  • Breakpoints allow you to mark code that signals the debugger to pause execution. After you encounter a breakpoint, you can choose to continue step-by-step execution or resume the normal execution by pressing F5 or by clicking the Resume or Continue button.

  • The various tool windows, such as Me, Locals, Immediate, Autos, Watch, and Call Stack, can be of great help in tracking the execution path and the status of variables in the process of debugging an application in Visual Studio .NET.

  • When an exception is thrown by an application, you can either choose to continue execution or break into the debugger (in order to start debugging operations such as step-by-step execution). You can customize this behavior for each exception object by using the Exceptions dialog box.

Debugging a Running Process

Up to this point, you have only seen examples of debugging programs by starting them from the Visual Studio .NET environment. The Visual Studio .NET debugging environment also allows you to debug processes that are started outside the debugging environment.

To access external processes from Visual Studio .NET, you need to invoke the Processes dialog box, shown in Figure 9.29, which you can do in two ways:

  • When you have a solution open in Visual Studio .NET, you can invoke the Processes dialog box by selecting Debug, Processes.

  • When no solution is open in Visual Studio .NET, the Debug menu is not displayed. However, you can invoke the Processes dialog box by selecting Tools, Debug Processes.

Figure 9.29. The Processes dialog box allows you to attach a debugger to a process that is under execution.

In the Processes dialog box, select the process that needs to be debugged in the Available Processes section and then click the Attach button to attach the process to the debugger. You can then open the source code files in Visual Studio .NET and place breakpoints in the code. The Visual Studio .NET debugger breaks the execution of the process when the breakpoint is reached. You can invoke various debugging windows, such as the Watch, Locals, Autos windows to analyze variables and step through the program execution.

Step by Step 9.9 demonstrates how to attach the debugger to a process that is being executed.

EXAM TIP

SMS 1.0 Based Questions The location of the SMS.INI file was the root of the C:\ drive in SMS version 1.0, which has been changed in version 1.2.


STEP BY STEP

9.9 Attaching the Debugger to a Process That Is Being Executed

  1. Using Windows Explorer, navigate to the bin folder inside the project folder for StepByStep9-8 . Double-click the StepByStep9-8.exe file to launch the program.

  2. Start a new instance of Visual Studio .NET and select Tools, Debug Processes. The Processes dialog box appears, as shown in Figure 9.29. You might have a different process list from what is shown in the figure.

  3. Select the process named StepByStep9_8.exe in the Available Processes section and click the Attach button. This invokes an Attach to Process dialog box, as shown in Figure 9.30. Select the Common Language Runtime as the program type and keep all other options unchecked. Click the OK button. You should now see the selected process in the Debugged Processes section of the Processes dialog box.

    Figure 9.30. The Attach to Process dialog box allows you to attach a debugger to a program that is running in a process outside of Visual Studio .NET.

  4. Click the Break button to break into the running process. Click the Close button to close the Processes dialog box for now.

  5. The source code window opens in the debugging environment. Switch to the source code window. Set a breakpoint on the line of code that makes a call to the Factorial() method. Press F8 to step into the program.

  6. Enter the value 5 in the form and click the Calculate button. The debugger breaks the execution when the breakpoint is reached.

  7. Invoke the Watch, Locals, Autos window to analyze variables and step through the program execution.

  8. When the factorial result is displayed, invoke the Processes window again by selecting Debug, Processes. From the list of debugged processes, select StepByStep9-8 and click the Detach button.

  9. Click the Close button to close the Processes dialog box. StepByStep9-8.exe is still executing as it was when you initiated the debugging process.

WARNING

Terminating aspnet_wp.exe The ASP.NET worker process ( aspnet_wp.exe ) processes requests from all ASP.NET applications. If, after debugging, you choose to terminate the aspnet_wp.exe process, it will affect all Web applications running on the server. You need to be especially careful when selecting this option on a production/shared server. The server will restart the process as necessary, but session and application state information will be lost.

Don't Debug on a Production Server When you attach a debugger to the ASP.NET worker process aspnet_wp.exe , it freezes the execution of all other Web applications on that server. This might cause undesirable effects on a production server.


To debug a deployed or running Web application or a Web service, you need to attach the Visual Studio .NET debugger to the aspnet_wp.exe process running on the Web server. After this debugging setup is done, the Web programs can be debugged just like any other program.

Debugging a Remote Process

The process of debugging a remote process is almost the same as debugging an already running process. The only difference is that, prior to selecting a running process from the Processes dialog box, you must select the remote machine name from the Name drop-down list box in the Processes dialog box.

Before you can debug a process remotely, you need to perform a one-time configuration on the remote machine (where the processes are running). You can do this in two ways:

  • Install Visual Studio .NET on the remote machine.

  • Install the Remote Components Setup on the remote machine (you can start this from the Visual Studio .NET Setup Disc 1).

NOTE

Microsoft CLR Debugger ( dbgclr .exe ) The .NET Framework provides a tool called Microsoft CLR Debugger ( dbgclr.exe ). This tool is based on the Visual Studio .NET debugger and has almost the same features. This tool will be especially useful if you are not using Visual Studio .NET for developing your applications and still want all the powerful GUI-based debugging capabilities.


In addition to this, you must ensure that your user account is a member of the Debugger Users group on the remote machine. If you want to debug the ASP.NET worker process, you must also have administrative privileges (that is, you should be a member of the Administrators group) on the remote machine.

EXAM TIP

Debugging a Remote Process The local computer and the remote computer must be members of a trusted domain in order for remote debugging to be possible.

DCOM Error While Debugging Visual Studio .NET uses DCOM to enable remote debugging. If you get a DCOM configuration error while debugging, you didn't set up the remote machine to support remote debugging. To resolve the error, make sure that you follow all the steps mentioned in this section.


If SQL Server is installed on the remote machine, the setup process just scribed also configures the machine for SQL Server stored procedures debugging, which is demonstrated at the end of this chapter, in Exercise 9.2.

After you have completed the required setup, the process of debugging a remote process is almost the same as the process of debugging an already running process. The only difference is that prior to selecting a running process from the Processes dialog box, you need to select the remote machine name from the Processes dialog box (refer to Figure 9.29).

Debugging the Code in DLL Files

The process of debugging a DLL file is similar to the process of debugging an EXE file. There is one difference though: The code in the DLL file cannot be directly invoked, so you need to have a calling program that calls various methods/components of the DLL files.

You typically need to take the following steps in order to debug code in a DLL file:

  1. Launch the program (such as an EXE file, a Web page, a Web service, and so on) that uses the components or methods in the DLL file.

  2. Launch Visual Studio .NET and attach the debugger to the calling program. Set a breakpoint in the calling program in which the method in the DLL file is called or else in the source code of the DLL file. Continue with the execution.

  3. The execution breaks when the breakpoint is reached. At this point, select Debug, Step Into to step into the source code of the DLL file. Execute the code in the step mode while you watch the value of its variables.

In addition, if the code files are executing on a remote machine, you need to make sure that the remote machine is set up with remote debugging support, as explained in the previous section.

Debugging Client-Side Scripts

Visual Studio .NET also allows you to debug client-side scripts. The process is similar to the process that I discussed earlier for ASP.NET Web forms. However, you must note the following additional points for client-side scripting:

  • Client-side debugging only works with Microsoft Internet Explorer.

  • You have to enable script debugging in Internet Explorer. To do this, select Tools, Internet Options, select the Advanced tab, and uncheck the Disable Script Debugging option in the Browsing section.

  • Attach the debugger to the iexplore.exe process displaying the Web form. This is only required if you are debugging an already running process. While attaching the process, in the Attach to Process dialog box, make sure that you also select the Script option.

Debugging a Windows Service

In most aspects, debugging a Windows service is like debugging any other application. However, a Windows service runs within the context of the Service Control Manager. Therefore, in order to debug a Windows service, you must attach a debugger to the process in which the Windows service is running. If the Windows service is not already started, you need to start the Windows service to perform debugging.

WARNING

Debugging Windows Service Processes When you attach a debugger to a Windows service, the service suspends its processing, but continues to be in the Started state. This might affect the functionality of the Windows service. Therefore, you need to be especially careful when selecting this option on a production/shared server.


Step by Step 9.10 shows you how to debug the OrderService service created in Step by Step 6.1 in Chapter 6, "Windows Services." If you haven't already created this service, you should create it now so that you can complete Step by Step 9.10.

STEP BY STEP

9.10 Debugging Windows Services

  1. Open the 310C06 solution from Chapter 6 in Visual Studio .NET.

  2. Open the OrderService.vb file of the StepByStep6-1 project. This file contains the code for the Windows service.

  3. Place a breakpoint in the fswOrders_Created() method where the main task of the Windows service is performed.

  4. Make sure that the OrderService is already installed. If not, install the service by following the steps in Step by Step 6.3 in Chapter 6.

  5. Open the Services administrative tool from the Administrative tool section of the Windows Control Panel. Browse through the services to locate OrderService service. Ensure that the Windows service is running; if not, start the Windows service.

  6. Select Tools, Debug Processes. The Processes dialog box appears. Select the process named StepByStep6-1.exe ( OrderService Windows service) in the Available Processes section and click the Attach button. This invokes an Attach to Process dialog box. Select the Common Language Runtime option. Click the OK button. You should now see the selected process in the Debugged Processes section of the Processes dialog box. Click the Close button to close the Processes dialog box for now.

  7. Create an XML file named Orders.xml and copy this file to the c:\orders directory. Refer to Step by Step 6.3 for more details.

  8. Note that in a few moments the debugger breaks into the fswOrders_Created() method in the OrderService.vb file, where the breakpoint was placed. You can now step into the code of the Windows service and step through the program execution. Invoke Watch, Locals, Autos window to analyze variables and step through the program execution.

  9. When the Orders.xml file is moved from c:\orders to a new subdirectory c:\orders\updated , invoke the Processes dialog box again by Selecting Debug, Processes. From the list of debugged processes, select StepByStep6-1 and click the Detach button.

  10. Click the Close button to close the Processes dialog box. Note that OrderService Windows service ( StepByStep6-1.exe ) is still running, as it was when you initiated the debugging process.

In Step by Step 9.10, you could have placed breakpoints in the OnStop() , OnPause() , OnContinue() methods. You could have then used the Services administrative tool to stop, pause, or continue the Windows service in order to debug the code in these methods. However, it is not possible to debug the OnStart() method (that starts the service) or the Main() method (that creates the instance of the service) by the process explained in Step by Step 9.10 because a Windows service needs to already be started in order to attach a debugger.

If a Windows service is executing on a remote machine, you need to make sure that the remote machine is set up with remote debugging support, as explained in the section "Debugging a Remote Process."

Debugging a Serviced Component

A serviced component is stored in a DLL file. The code in the serviced component cannot be directly invoked, so you need to have a client (calling) program that creates the serviced component object and calls various methods of the serviced component.

Therefore, to debug a serviced component, you need to take steps similar to that of debugging any DLL file. However, the debugging differs slightly depending on whether the serviced component application is a Library or Server application.

If the serviced component is a Library application, the serviced component runs in the process of the client application. In this case, you can set breakpoints in the serviced component or the client application and run the client application in debug mode. When the breakpoint is reached, you can step into the code of the serviced component. In the case of an already running client application, you can set breakpoints in the serviced component or the client application and attach a debugger to the client application's process.

On the other hand, if the serviced component is a Server application, the serviced component runs in a separate process called dllhost.exe . Setting breakpoints in the client code and attaching a debugger to the client application will only debug the client application; it will not step into the code of the serviced component.

In this case, to debug the serviced component, you should place breakpoints in the serviced component code and attach a debugger to the dllhost.exe process in which the desired serviced component is running. If multiple COM+ server applications are running on a machine, multiple dllhost.exe processes will be running on the machine.

You can identify the unique process identifier (PID) of the dllhost.exe that is running your serviced component with the help of Component Services administrative tool. Drill-down to the COM+ Applications node and select View, Status View. You should now be able to view the PID for the dllhost.exe process that hosts the serviced component, as shown in Figure 9.31.

Figure 9.31. The Status View of the Component Services administrative tool gives detailed information on the status of the COM+ applications.

You can use the PID of the dllhost.exe process to attach a debugger to that process using the Processes dialog box, as shown in Figure 9.32.

Figure 9.32. An Enterprise Services application that has Server activation mode, which is run in a separate process named dllhost.exe.

After attaching to the process, you can place breakpoints to step into the code of the serviced component just like any other component. If you want to debug the client application as well, you should attach a debugger to the client application's process. So, in this case, you attach debuggers to two processesthe serviced component's process and the client application's process.

However, note that while debugging, serviced components involving transactions might raise COMException errors indicating a transaction timeout problem. The default computer level setting of a transaction timeout is 60 seconds. While debugging, you might want to increase the transaction timeout value. You can do so by overriding the default settings for your serviced component by selecting the Override global transaction timeout value option in the Transactions tab of the serviced component's Properties dialog box, as shown in Figure 9.33.

Figure 9.33. You can set the timeout value for the serviced component's transactions in the serviced component's Properties dialog box.

Note the default value for the timeout if overridden is 0, which means that the transactions will never timeout. In most cases, you should set a value greater than 0 so that there are no chances of distributed deadlocks.

If you are debugging multiple serviced components that involve transactions, instead of increasing the timeout value for each serviced component, you can choose to increase the computer level setting of the default timeout value. You can do this by changing the Transaction Timeout value in the Options tab of the My Computer Properties dialog box, as shown in Figure 9.34. You can open this dialog box by selecting Properties from the context menu of the My Computer node in the Component Services administrative tool.

Figure 9.34. You can set the timeout value for all the distributed transactions in a computer in the My Computer Properties dialog box.

If a Serviced component is executing on a remote machine, you need to make sure that the remote machine is set up with remote debugging support, as explained in the section "Debugging a Remote Process."

Debugging a .NET Remoting Object

A .NET remoting object is stored in a DLL file in the same manner as a serviced component. A .NET remoting object executes in the process of the remoting server application irrespective of its activation mode.

Therefore, to debug a remoting object, you need to take the following steps:

  1. If the remoting server is running in its own process, attach the debugger to that process.

  2. If the remoting server is hosted in IIS, attach a debugger to the ASP.NET worker process ( aspnet_wp.exe ).

  3. Set breakpoints in the remoting object class definition.

After taking these steps, the Visual Studio .NET debugger breaks the execution when it reaches the breakpoint in the code.

WARNING

Setting the Computer Level Default Timeout When you increase the Transaction timeout value in the My Computer Properties dialog box, the setting affects all the transactions in the computer. Therefore, you should try to reset the default value as soon as possible so that other applications using transactions are not affected in the computer.


Attaching a debugger to the process in which a Remoting client application is running will only debug the client application and will not step into the code of the remoting object class definition. In order to debug both client and server applications, you can attach a debugger to both the applications and step seamlessly into the code of both the applications.

If a remoting object is executing on a remote machine, you need to make sure that the remote machine is set up with remote debugging support, as explained in the section "Debugging a Remote Process."

Debugging an XML Web Service

Debugging XML Web services is similar to debugging Web applications. They also run in the ASP.NET worker process ( aspnet_wp.exe ). You only need to set breakpoints in the Web methods of the Web service. After setting breakpoints, you can debug Web services in any of the following methods:

  • You can run a Web service from Visual Studio .NET and then step into the code of the Web service by invoking the methods through the Web service test page.

  • You can also attach a debugger to the aspnet_wp.exe process to step into the code of an already running Web service.

  • You can create a client application for the Web service that invokes its Web methods. You can then step into the code of the Web service by running the client application from Visual Studio .NET.

  • You can attach a debugger to an already running client application and then step into the code of the Web service when the code reaches a breakpoint.

You should also make sure that the Web service application is configured for debugging. Refer to "Configuring the Debugging Environment" section, discussed earlier in the chapter, for more details. Also, if the Web service is executing on a remote machine, you need to make sure that the remote machine is set up with remote debugging support, as explained in the section "Debugging a Remote Process."

You can also use SOAP extensions to help debug Web Services. These SOAP extensions can be used to examine or modify the SOAP messages sent and received by the Web service or the client. Refer to the section "Creating and Using SOAP Extensions" in Chapter 5, "Advanced Web Services," for how to create and use SOAP extensions.

REVIEW BREAK

  • You can attach the debugger to a running process (either local or remote) with the help of Processes dialog box.

  • When you attach a debugger to the ASP.NET worker process aspnet_wp.exe , it freezes the execution of all other Web applications on that server.

  • You should have mdm.exe running on the remote machine in order to perform remote debugging.

  • To debug a Windows service, you must attach a debugger to the process in which the Windows service is running.

  • To debug COM+ library applications, you must attach a debugger to the process in which the client application is running.

  • To debug COM+ server applications, you must attach a debugger to the dllhost.exe process in which the COM+ server application is running.

  • To debug a .NET remoting object, you must attach a debugger to the process in which the remoting server application is running. In case the object is hosted in IIS, you need to attach a debugger to the aspnet_wp.exe process.

  • To debug a Web service, you need to attach a debugger to the aspnet_wp.exe or the client application that is calling Web methods of the Web service.


   
Top


MCAD. MCSD Training Guide (Exam 70-310. Developing XML Web Services and Server Components with Visual Basic. NET and the. NET Framework)
MCAD/MCSD Training Guide (70-310): Developing XML Web Services and Server Components with Visual Basic(R) .NET and the .NET Framework
ISBN: 0789728206
EAN: 2147483647
Year: 2002
Pages: 166

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net