Debugging Web Services

Interactive Debugging

One of the most powerful tools in a developer's arsenal is the debugger. A debugger allows you to attach to a process, peer into its state, and, depending on the debugger, even control the flow of the application. If the debugger supports remote debugging, the target process can be located on another machine.

You have many choices of debuggers for your .NET Web services. The .NET Framework ships with two debuggers, the CLR Debugger (DbgCLR.exe), which is Microsoft Windows based, and the Runtime Debugger (CorDbg.exe), which is command-line based. Visual Studio .NET also has its own debugger. In addition, you can choose from a number of third-party debuggers.

In this section, I discuss functionality supported by most debuggers. However, my examples will be based on the Visual Studio .NET debugger.

I assume that you have basic knowledge of how to debug applications. For example, I do not cover topics such as stepping through code and setting breakpoints. If you are unfamiliar with these concepts, I suggest you learn about them before proceeding further.

The Basics of Debugging

One of the strengths of Visual Studio .NET is its tight integration with the run-time environment. For example, when you build an ASP.NET Web service project, Visual Studio .NET will automatically deploy the application to the Web server.

This integration extends to support for debugging Web services. As you know by now, you can start debugging a Web service by pressing F5. A reasonable amount of work will be done for you. Visual Studio .NET will automatically perform the following tasks:

  1. Compile the Web service. This will help ensure that the compiled application matches the underlying source code.

  2. Deploy the Web service. Visual Studio .NET will deploy to the Web server the newly compiled DLL and any other files that have changed. You can deploy the Web service by using Microsoft FrontPage Server Extensions or by using a file share that is mapped to the underlying file system hosting the Web service.

  3. Launch the .asmx page within the browser. This will cause the ASP.NET worker process to load the Web service application.

  4. Attach to the ASP.NET worker process. To do this, the Visual Studio .NET debugger locates the correct ASP.NET worker process running the Web service, even if it is running on a different machine.

The technology that enables Visual Studio .NET to automatically locate and attach to the remote ASP.NET process that is hosting a Web service has a powerful derivative: While you are debugging a Web service client, when you get to the line that calls to the Web service via a proxy, you can press F11 to step into the implementation of the Web service method. Visual Studio .NET will intercept the call to the Web service, attach to the process, and then set a breakpoint at the beginning of the method.

This feature is referred to as causality. To facilitate causality, the Web service client must have appropriate security rights. If the Web service client is an ASP.NET application, the default account under which the application runs does not have sufficient permissions to facilitate causality. Therefore, to enable this feature, you must modify the userName and password attributes of the processModel element in the machine.config file so that the ASP.NET application calling the Web service runs under an account with administrative privileges. See Chapter 10 for more information.

After you are finished debugging your managed code application, you can detach from the process and it will continue to execute. However, if your application also invokes unmanaged code and you want to debug it as well, you will not be able to detach from the process without terminating it.

One way to overcome this limitation is to install the dbgproxy service. After you are finished debugging unmanaged code, dbgproxy will keep the debug handles open for you. You can then detach from the process without terminating it.

You can install dbgproxy by executing the following commands:

dbgproxy –install net start dbgproxy

The first command installs the dbgproxy service, and the second command starts it.

Remote Debugging

To facilitate some of the remote debugging features described in the previous section, you must make sure that your environment is properly configured. If you have had, shall we say, a less than optimal experience configuring remote debugging in previous versions of Visual Studio, you will be pleasantly surprised by how simple and straightforward this task is in Visual Studio .NET.

The machine that hosts the remote process must have a collection of COM components installed. The easiest way to install these components is to install Visual Studio .NET on that machine. In most cases, especially if the machine is in the production environment, this solution would be suboptimal, so Visual Studio .NET setup gives you the option of installing only the remote debugging components.

To install the remote debugging components, insert the Visual Studio .NET setup disk into the target computer and select the Remote Components Setup link at the bottom of the opening screen, as shown in the following graphic.

Remote debugging is facilitated through DCOM. Therefore, once you have installed the remote debugging components, you must make sure that you have sufficient permissions to attach to and debug the target process on the remote machine. In order to simplify this process, Setup creates a local group on the target machine called Debugger Users.

Users added to the Debugger Users group will have sufficient permissions to conduct a remote interactive debugging session. However, they also need permissions to attach to the process itself.

By default, the ASP.NET worker process hosting the Web service will run under the System user account. Adding yourself to the local Administrators group will give you sufficient permissions to attach to the worker process. However, if doing so is unacceptable with your system administrator, work with her to configure the machine to achieve the desired security exposure.

Web Services–Friendly Call Stack

A call stack is a data structure that is used to keep track of information about nested calls made by a particular thread within an application. For each nested call, a stack frame is created and added to the call stack. For example, if the Main method within an application calls method X on object A and method X in turn calls method Y on object B, you will have a call stack containing three stack frames, as shown here:

The stack frame tells the computer how to return control to the caller once a method has finished executing. Once the method returns, its stack frame is popped off of the call stack.

The stack frame also contains the parameters that were passed to the method, plus other housekeeping data. Visual Studio .NET can interpret the individual stack frames on the stack to obtain information about the current state of a particular thread. When execution of an application domain is suspended, you can view the following information from within the Call Stack window:

  • The name of the module that contains the implementation of the method

  • The names, types, and current value of the method's parameters

  • The line number currently being executed within the method

  • The language in which the method was implemented

Knowing the sequence of calls that were made and the value of each parameter that was passed can be invaluable when you are trying to debug your application. However, if one of the methods calls into a Web service, the continuity of the call stack will be broken. Because the Web service will be executed on a different thread, and more than likely on a different machine, it will have its own call stack.

Visual Studio .NET simplifies debugging applications that span multiple processes and multiple machines by providing a consolidated view of the call stacks that compose a single logical thread of execution. You can see the entire call chain by right-clicking in the Call Stack Window and choosing Include Calls To/From Other Threads.

To ensure that you have a complete call stack, you must rethrow exceptions correctly within your application. To rethrow an exception, you call throw without any parameters. If you pass the exception as a parameter to throw, the stack will unwind to the stack frame to the method throwing the exception and the final recipient of the exception will not have a complete stack trace.

Here is an example of two different ways to rethrow an exception:

try {     // Implementation... } catch(SystemException se) {     // Causes the stack to unwind to this method call     throw se; } catch(ApplicationException ae) {     // The recipient of the exception will have a full stack trace.     throw; }

Your application might use code to which you do not have the source that improperly throws an exception. To facilitate obtaining a full stack trace, you can configure Visual Studio .NET to catch first-chance exceptions. Choose Debug, Exceptions to open the Exceptions dialog box. Click Common Language Runtime Exceptions, and then select the Break Into The Debugger option in the When The Exception Is Thrown section, as shown here:



Building XML Web Services for the Microsoft  .NET Platform
Building XML Web Services for the Microsoft .NET Platform
ISBN: 0735614067
EAN: 2147483647
Year: 2002
Pages: 94
Authors: Scott Short

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