Chapter 22
Debugging with IntelliTrace

What's in this chapter?

  • Exploring how to run IntelliTrace
  • Configuring IntelliTrace options
  • Running IntelliTrace in a production environment

wrox.com Code Downloads for this Chapter

The wrox.com code downloads for this chapter are found at www.wrox.com/go/proalm3ed on the Download Code tab. The files are in the Chapter 22 download folder and individually named as shown throughout this chapter.

Many developers resent the fact that debugging has become one of the key components in software development. They have been known to spend a considerable amount of time simply on debugging. Adding salt to the wound are programming bugs for which the behavior is not reproducible. In many instances, developers may wish there was a way to travel back in time to capture what happened and then be able to wave a magic wand to debug the issue. That wish has now come true in Visual Studio Ultimate 2013. (Not the magic wand part — that feature did not make the cut.)

This chapter examines the IntelliTrace feature, which debuted in Visual Studio 2010 Ultimate and has been enhanced in Visual Studio Ultimate 2013. In this chapter, you find out how to use this feature to aid in your debugging effort, and how you can use it in a production environment to help debug production applications.

IntelliTrace Basics

In many cases, as a developer, you have discovered that debugging is a regular activity. It is also a task that can become monotonous. For example, at some point a tester might have passed on a bug to you that you could not reproduce. You may also have experienced the agony of stepping through one step past the point where the issue occurs, only to discover that it is time to start all over again. These are just a couple of common occurrences, and there are no doubt plenty more.

Visual Studio Ultimate 2013 includes capabilities to address issues such as the famous “no repro” bug status. A key feature in this capability is the IntelliTrace feature. The key tactics used to address the nonreproducible bug are to capture as much information as possible when the bug is encountered, and to use the capability to leverage this information while debugging. The one feature that could top this would be for the bug to automatically resolve itself.

Now it's time to take a deeper look at this debugging feature through an example.

IntelliTrace — An Example

The following steps walk you through an example of using IntelliTrace to debug an application:

  1. To get started, open the Chapter22SampleApp in Visual Studio 2013. Press F5 to compile and run the application.

    The application runs, and a window with three buttons opens, as shown Figure 22.1. By pressing F5 to run the application, you are running it in Debug mode. Notice the IntelliTrace window on the right side of Visual Studio. Currently nothing is shown in the window. IntelliTrace gathers data behind the scenes while the application is executing, but you must break the execution of the application before the IntelliTrace information can be viewed. Let's walk the application through its paces and look at the IntelliTrace results.

  2. Click the Ex1: Generate Random Number button on the application form to generate a random number and display it in a message box. Click the OK button to close the message box.
  3. Click the Ex2: File Access button. The application attempts to read from a text file and displays the results in the textbox. You should see results displayed there.
  4. Click the Ex3: File Access button. The application attempts to read and display the contents of a different text file. Notice, however, that the application did not display anything. Something must be wrong with the application. However, the application did not throw an error or display any other signs that something is wrong.
image

Figure 22.1

At this point, before IntelliTrace, you would have had to go back into the code and look at the functionality around the application to try to determine where something might be wrong. Maybe you would have gone back in to add a lot of breakpoints, and then started stepping slowly through your code. Regardless, you had to go back and run the same tests again. With IntelliTrace, you don't have to do that.

The application did not perform as expected when you clicked the Ex3: File Access button. Use IntelliTrace to figure out why. In the IntelliTrace window in Visual Studio, click the Break All link. This breaks into the debugging session and displays the IntelliTrace information collected so far, as shown in Figure 22.2.

image

Figure 22.2

By default, IntelliTrace is configured only to capture IntelliTrace event information, so that is what is displayed initially in the window. Selecting a particular event in the window displays detailed information about the event, as well as navigates you to the code responsible for the event. For example, if you click the Gesture: Clicked “Ex1: Generate Random Number” event, the window displays detailed information related to the event and navigates to the Form1.cs tab and to the btnEx1_Click method that caused the event to fire. As a result, you can easily find the code related to the different IntelliTrace messages you may receive.

Looking through the IntelliTrace captured events, you can see two exception events. Select the Exception: Thrown event as shown in Figure 22.3.

image

Figure 22.3

Selecting the exception event displays detailed information about the event. In this case, you see that a File Not Found exception was thrown and that the application could not find the file named test2.txt. At the same time, in the Form1.cs tab, Visual Studio navigates to the AccessFile2 method and to the offending line of code. From this, you are able to determine that the test2.txt file does not exist, which must be causing the application problem. You are able to determine all this during the same initial test run without having to restart the application or rerun any tests.

Navigating the IntelliTrace Events View

As you can imagine, for a long-running test or debugging session, the IntelliTrace events view could contain a large number of events. The IntelliTrace window has several options to make it easier to navigate the event information.

There are two drop-down boxes at the top of the IntelliTrace window. The one on the right is the Threads drop-down box. This enables you to view all the application threads for which the IntelliTrace event information was captured, and you can select only the specific threads you want to view in the window. The second drop-down box (on the left) displays all the different event categories for which IntelliTrace was configured to monitor for the particular test run. You can uncheck specific categories to remove those events from the window.

Finally, there is a search box underneath the two drop-down boxes, which you can use to search for particular words or phrases for the displayed events. For example, if you only want to display the Exception events, you can enter the word Exception in the search box and click the magnifying glass search icon. The contents of the window are filtered to only show events that contain the word Exception.

Collecting Method Call Information

As mentioned earlier, by default, IntelliTrace only collects specified event information. You can also configure IntelliTrace to collect method call information. Think of this as another way to navigate through the call stack, but you can see details around the call information. To set this, in Visual Studio, select Tools⇒Options. The Visual Studio Options window opens. Select the IntelliTrace setting's General tab, shown in Figure 22.4.

image

Figure 22.4

On this tab, you can turn IntelliTrace on or off for debugging sessions by selecting or deselecting the Enable IntelliTrace checkbox. You can also control what information IntelliTrace collects. As mentioned earlier, by default IntelliTrace only collects event information, which has a minimal effect on application performance. However, you can configure IntelliTrace to gather both event and method call information by selecting the IntelliTrace Events and Call Information radio button.

You should consider some things before selecting this option, though. This option collects detailed method call information, which leads to some application performance degradation. Also, the Edit and Continue features of the debugger are disabled as call information is collected. Finally, this change does not take effect until the next debugging session, so if you have made this change while in the middle of debugging, call information is not collected unless you restart your session.

To continue the example, select the IntelliTrace Events and Call Information radio button and then click OK to close the options window. If you are currently in a debugging session in Visual Studio, stop the debugging session. Press F5 to compile and run the same application again. Click through all three buttons, as before, and then click the Break All link in the IntelliTrace window to break into the debugging session.

Select the User Prompt: Displayed ⇒ (MessageBox) event in the IntelliTrace window to display the event details. Click the Switch to IntelliTrace Calls View link to switch the context of the IntelliTrace view from events to call stack information (see Figure 22.5).

image

Figure 22.5

You can use this view to navigate the call stack and view some variable information. Double-click the Chapter22SampleApp.Form1.btnEx1_Click call to navigate to its call information. Then double-click the Chapter22SampleApp.Form1.GetRandomNumber call. You are navigated to the GetRandomNumber method in Form1.cs, as shown in Figure 22.6.

image

Figure 22.6

Figure 22.6 shows you more of the power of IntelliTrace when you're collecting method call information. IntelliTrace automatically collects all the input-parameter information for a method, as well as the method's return value. In the case of Figure 22.6, by looking in the locals window in the bottom left, you can see that the minValue was set to 0, the maxValue was set to 100, and the random number returned was 82. Again, it is worth pointing out that you are able to view all this information without having to remember to set specific breakpoints, or rerun the debugging process.

Having this data collection at the method entry and exit points enables you to treat the method as a black box, and can make it easier for you to determine why the method is providing the incorrect information or causing some other error.

When you are viewing IntelliTrace information in the call view, a navigation bar appears in the code window. You can see this navigation bar in Figure 22.6. You can use the navigation bar to walk through the call stack instead of clicking on call information in the IntelliTrace window. The navigation bar contains five icons that have the following associated actions. (This list is ordered to match the order of the icons in the navigation bar.)

  • Return to Call Site
  • Go to Previous Call or IntelliTrace Event
  • Step In
  • Go to Next Call or IntelliTrace Event
  • Go to Live Mode

Collecting Detailed Information

Try this. Assuming you are still in Visual Studio — in debugging mode and in the GetRandomNumber method from the last section — right-click the randomnumber variable in that method and select Add Watch from the context menu. This adds the variable randomnumber to the watch window. You might expect its value to be the same as the return value from the method (in this example, 83). However, as Figure 22.7 shows, the variable displays the message [Available IntelliTrace data is shown in the Locals window]. Wait, what? This is the variable that contains the value being returned by the function, so how could the value not be collected?

image

Figure 22.7

Although IntelliTrace collects a lot of valuable debugging information for you, it doesn't collect every little bit of information. Collecting all the information would lead to an extremely large collection file, which could ultimately be difficult to use. One of the places that IntelliTrace makes a trade off is with local variables. By default, local variable information is not captured via IntelliTrace collection. However, you can work around this by setting debugging breakpoints or tracepoints in your code. Setting a breakpoint or a tracepoint forces IntelliTrace to collect the local variable information at that break. Take a look at an example of this:

  1. If you are still in debugging mode in Visual Studio, select Debug⇒Stop Debugging to halt the debugging process. Double-click Form1.cs to open the file in Visual Studio. Navigate to the GetRandomNumber method and add a breakpoint on each of the following three lines:
    Random random = new Random();
    randomnumber = random.Next(minValue, maxValue);
    return randomnumber;
  2. Press F5 to run the application. Click the Ex1: Generate Random Number button. Visual Studio breaks into the application at the first breakpoint. Notice that you can make full use of IntelliTrace to move backward through the call stack, as well as view IntelliTrace event information. Click the Continue button on the Visual Studio toolbar to continue debugging.

    Visual Studio now breaks at the second statement. Hover the mouse over the randomnumber variable, and a data tip displays to show the current value of randomnumber. You can also see the value of randomnumber by looking in the Locals tab in Visual Studio. You see that the randomnumber value is currently equal to zero. This is because the debugger stopped the application before the line of code has executed.

  3. Click the Continue button on the Visual Studio toolbar to move to the return statement.

    At this point, the random number has been generated and stored in the randomnumber variable. You can see this by either viewing the variable in the Locals window or by hovering your mouse over the variable name in the method.

Saving Your IntelliTrace Session

By default, when you exit your debugging session in Visual Studio, your IntelliTrace information is automatically deleted. It is not saved. If you want to save your IntelliTrace information to later review and use, you need to explicitly save the results to a file. Saving the results to a file enables you to pass them on to another developer, who could then review your debugging session to try to resolve any exceptions that occurred.

To do so, in Visual Studio, select Debug⇒IntelliTrace⇒Save IntelliTrace Session. This opens a Save As window, where you can choose to save your IntelliTrace session as an .iTrace file. By default, the file includes a timestamp.

Now generate a new IntelliTrace session, save the IntelliTrace session to a file, and then view the file:

  1. If you are still in debugging mode in Visual Studio, select Debug⇒Stop Debugging to halt the debugging process. Make sure you have added the three breakpoints specified in the previous session and then press F5 to start debugging the application. Click through each of the buttons in the application to execute its functionality. When the breakpoints are triggered, simply click Continue on the Visual Studio toolbar to continue executing the application logic.
  2. After you have clicked all three buttons on the app, click the Break All link in the IntelliTrace window to break into the debugging session. From within the IntelliTrace window, you can click the Save icon to save the session information, or select Debug⇒IntelliTrace⇒Save IntelliTrace Session.
  3. Save the session to your Documents folder, and take the default name. This saves the IntelliTrace session information to the .iTrace file.
  4. Select Debug⇒Stop Debugging to stop the debugging process, and close Visual Studio.
  5. Open Windows Explorer and navigate to your Documents folder. You see a file similar to Figure 22.8. The important takeaway from this is how big the IntelliTrace session file is, even for the small amount of debugging that you performed. In this example, it is almost 14MB. Depending on the length of your debugging session, how much event information you are collecting, and how many breakpoints you have set to capture local variable information, this file can grow quite large.
image

Figure 22.8

You might expect the IntelliTrace file to be a simple XML file that you can open and view in a text editor, but that is not the case. Because of the amount of information gathered by IntelliTrace, the data is stored in a proprietary format to make it easier for Visual Studio to work with.

To open the IntelliTrace session file, simply double-click the session file, and it opens in Visual Studio (see Figure 22.9).

image

Figure 22.9

When you open an IntelliTrace session file, it initially displays the IntelliTrace summary screen. This summary screen can contain a good bit of initial information to help you understand the debugging session. In the following sections, you examine these sections.

Threads List

The Threads List section displays detailed information about the threads, including their thread IDs, thread names, and the start and end time of each thread.

Modules

The Modules section shows you all the different modules (DLLs, executables, and so on) for which data was collected during the IntelliTrace collection process. Information displayed here includes the module name, the module path, and the module ID.

System Info

The System Info section contains detailed system information about the machine on which the IntelliTrace information was collected, as shown in Figure 22.10.

image

Figure 22.10

Information collected includes total system memory, type of operating system, and processor information, just to name a few values. Having this machine information at your fingertips can make it easier to understand why the application might be having issues on a particular type of machine.

Exception Data

If any exceptions were triggered during the IntelliTrace collection process, that information is displayed here, as shown in Figure 22.11.

image

Figure 22.11

Select the System.IO.FileNotFoundException. The call stack for the exception is displayed, which shows you, in this case, that the Chapter22SampleApp.Form1.AccessFile2 method was triggered, and then several System.IO.File methods were triggered.

What is really interesting is that, when you select the exception, the Debug Newest Exception in Group button becomes enabled. Clicking this button actually puts Visual Studio into debug mode, navigates the IntelliTrace window to where the exception occurred, opens the code file associated with the exception, and navigates to the line of the file where the exception occurred (see Figure 22.12).

image

Figure 22.12

Notice that you are in full debugging mode, using the IntelliTrace file as the source information. As such, you only have access to the information that IntelliTrace collected. You can do anything that you would normally do when working with collected information, including view event information, navigate the call stack, and view variable information that was collected. Also, remember that the full solution has not been opened for you at this point, just the specific code file. This is to aid you in determining the root cause of the problem. After this is found, you should still open the entire solution before making the appropriate changes.

IntelliTrace Options

There are multiple options you can configure around IntelliTrace. Open the IntelliTrace settings window by clicking Debug⇒IntelliTrace⇒Open IntelliTrace Settings. The Visual Studio Options window displays, as shown in Figure 22.4.

You should notice the following four configuration sections within the IntelliTrace option node:

  • General
  • Advanced
  • IntelliTrace Events
  • Modules

Let's look at the configurations available in each of these sections.

General

You already learned about this section earlier in this chapter, but it's worth reviewing here. In the General section, you can enable IntelliTrace by clicking the Enable IntelliTrace checkbox. With this checkbox you can enable (check) or disable (uncheck) IntelliTrace. In this window, you can also choose between the options to record events only or collect additional information that includes events, diagnostics, calls, and method level tracing. Of course, collecting more information means that a larger log file is generated. As you can see in the Options window shown in Figure 22.4, collecting more information has more of an impact on performance than merely collecting events.

Also, note that the Edit and Continue option is disabled with the latter option. The Options dialog prompts you with this warning when you change the setting.

Advanced

The Advanced option provides several settings. As shown in Figure 22.13, you can set the location to store the generated log file, and specify the maximum size that the log file should be. Remember, this is important, as the IntelliTrace log files can grow to a very large size.

image

Figure 22.13

In addition, there are three checkboxes at the bottom of the screen:

  • Display the Navigation Gutter while in Debug Mode
  • Enable Team Foundation Server Symbol Path Lookup
  • Prompt to Enable Source Server Support

IntelliTrace Events

As shown in Figure 22.14, the IntelliTrace Events section lists all the diagnostic events that are collected while debugging an application. The list of events is broken down by framework categories. Here, you can select (that is, choose to collect) or deselect (choose not to collect) the diagnostic events shown on this list. This enables you to target your event collection to only the specific technologies you care about. By default, only a certain subset of events are collected.

image

Figure 22.14

Modules

As shown in Figure 22.15, this section enables you to manage the list of modules for which data is collected during debugging.

image

Figure 22.15

Here you can add new assemblies to collect debugging information, as well as exclude and remove assemblies for which you don't want to collect debugging information.

IntelliTrace in Production

With Visual Studio 2012, Microsoft released a set of IntelliTrace standalone collection utilities that you could use to create IntelliTrace logs and gather other debugging information about production applications. You didn't need Visual Studio 2012 installed on the machine being tested and the utilities themselves didn't alter the computer they were on, and removing the utilities is as simple as deleting a folder. This made it easy to install and use these utilities on production web servers, as well as other computers.

With Visual Studio 2013, things have change slightly. You can still use IntelliTrace to gather information about production applications. However, now you do this by installing the Microsoft Monitoring Agent (MMA).

MMA is used to monitor the health of your applications as well as your computer infrastructure. It can be installed and used as a standalone tool, gathering IntelliTrace information, or it can be connected to System Center Operations Manager (SCOM) to calculate the health states of the computer and objects, and report that information back to the SCOM management server for analysis and reporting. When used as a SCOM agent, you can start to reap the benefits of SCOM Application Performance Monitoring (APM). With APM, SCOM can monitor your web applications. When issues arise, you can use the SCOM console to automatically start an IntelliTrace session, to gather debugging information. There is integration between SCOM APM and TFS, such that alerts in SCOM can be turned into work items in TFS. And this integration allows you to take the IntelliTrace log that was generated using SCOM APM, and attach it to the associated work item in TFS. This allows IT pros to work in their environment (the SCOM console) while developers can stay in their environment (Visual Studio and TFS), but still easily communicate and share artifacts to aid in solving problems quickly.

When used as a standalone tool, the MMA can collect IntelliTrace application traces locally. It can be used to monitor IIS-hosted ASP.NET web applications, as well as Microsoft SharePoint 2010/2013 applications. PowerShell commands are used to start and stop the monitoring process, as well as collect IntelliTrace log files, which can then be examined using Visual Studio Ultimate 2013.

Installing the IntelliTrace Standalone Collector

To get started collecting IntelliTrace information in a production environment, you first need to download and install the Microsoft Monitoring Agent on the machine in question. You can download the installation file from http://www.microsoft.com/en-us/download/details.aspx?id=40316.

Make sure that your web server has .NET Framework 3.5, 4.0, or 4.5 installed on it. Ideally your web server also needs to have Windows PowerShell 3.0 or later installed. The MMA will work with Windows PowerShell 2.0, but you will have to import the MMA PowerShell commandlets every time you want to use it and run PowerShell.

The installation is very straightforward. At one step in the installation, you can configure the agent setup options, as shown in Figure 22.16.

image

Figure 22.16

Here, you can specify the setup options for the installation of the MMA. By default, the first two options are selected and greyed out, which doesn't allow you to change them. Those two options allow for the local collection of IntelliTrace logs, and allow use of the Active Directory to configure the agent based on centrally administered settings. The last option allows you to connect the agent back to your System Center Operations Manager environment, if you have one. This allows the MMA to act as a full SCOM agent and monitor your computer for various items, as well as gather IntelliTrace data.

As part of the installation, a control panel applet named Microsoft Monitoring Agent is installed in the computer's Control Panel application. This applet displays property information related to the agent, as well as allows you to configure the SCOM management groups to which it can report.

Once you are finished installing MMA, you need to create a folder to store your IntelliTrace logs in, for example C:IntelliTraceLogs. Make sure to create this folder before you start collecting IntelliTrace data. To avoid slowing down your application too much, consider choosing a location for this folder on a local high-speed disk that is not very active. Remember, to run detailed, function-level monitoring or to monitor SharePoint applications, you will need to give the application pool that hosts your web application or SharePoint application read/write permission to the IntelliTracelogs directory.

Configuring IntelliTrace PowerShell Commandlets

To collect IntelliTrace data in a production environment, you need to run a PowerShell commandlet (or cmdlet) on the machine. You need to open a PowerShell window as the administrator (hold down the Shift key, right-click the PowerShell icon, and select Run As Administrator from the context menu).

After running this command, you can run the following command to see the list of available IntelliTrace commands:

Get-Help *WebApplicationMonitoring*

There are four cmdlets available:

  • Checkpoint-WebApplicationMonitoring—Creates a checkpoint (think snapshot) of an active IntelliTrace log file for an Internet Information Services (IIS) web application.
  • Get-WebApplicationMonitoringStatus—Gets the monitoring status of all monitored web applications.
  • Start-WebApplicationMonitoring—Starts IntelliTrace collection on an IIS web application.
  • Stop-WebApplicationMonitoring—Stops IntelliTrace collection on an IIS web application.

Collecting Execution Information

To start collecting IntelliTrace information on a web application, use the following syntax in the PowerShell window:

Start-WebApplicationMonitoring AppName MonitoringMode
      OutputPath UInt32 collectionPlanPathAndFileName

Where:

  • AppName—Specifies the path to the website and the web application name in IIS.
  • MonitoringMode—Specifies the monitoring mode. Monitor uses the default collection plan, and records minimal details about exception events and performance events. Trace collects function-level details or monitors SharePoint 2010/2013 applications, using a specified collection plan.
  • OutputPath—Specifies the full directory path to store the IntelliTrace logs.
  • UInt32—Specifies the maximum size for the IntelliTrace log. The default maximum size is 250MB. When the log reaches this limit, the agent overwrites the earliest entries to make space for more entries.
  • CollectionPlanPathAndFileName—Specifies the full path or relative path and the file name of the collection plan. This plan is an .xml file that configures settings for the agent.

The MMA contains two collection plan files:

  • collection_plan.ASP.NET.default.xml—Collects only events, such as exceptions, performance events, database calls, and web server requests.
  • collection_plan.ASP.NET.trace.xml—Collects function-level calls, plus all the data in the default collection plan. This plan is good to use for detailed analysis, but may slow down your application.

After executing the preceding command, IntelliTrace is now running, gathering information about the web application. To find the current collection status, you can run the Get-IntelliTraceCollectionStatus WebApplicationStatus PowerShell cmdlet.

As a best practice, you shouldn't leave IntelliTrace running any longer than is necessary. There is an overhead cost on the system being collected against, depending on the detail of information collected. However, if you want to examine the data that has been captured so far, without stopping the collection process, run the Checkpoint-WebApplicationMonitoring cmdlet. This makes a copy of the .iTrace file at that particular point in time. You can then open this file and analyze it in Visual Studio while IntelliTrace continues to gather information. When you are ready to stop gathering data, simply run the Stop-WebApplicationMonitoring cmdlet.

When you have the IntelliTrace .iTrace log file from the production system, you can open it in Visual Studio Ultimate 2013 and begin your analysis, as described earlier in this chapter.

Summary

This chapter introduced you to IntelliTrace and showed you how its debugging features can be used to “step back in time” while you're debugging an application. You learned how to utilize IntelliTrace at a basic level to examine events that are thrown during the debugging process. You saw how IntelliTrace lets you step forward and backward through the debugging process — with the ability to view variable and parameter information — without having to rerun your tests.

You found out how to configure IntelliTrace, to capture just event information or both event and method call information. You walked through the different configuration options, such as where to store IntelliTrace log files, and how to exclude certain assemblies from collection.

Finally, you read about a new feature of IntelliTrace in Visual Studio 2013: the ability to collect IntelliTrace data in a production environment using the Microsoft Monitoring Agent. Using MMA, you can collect IntelliTrace log files against production web applications, making it much easier to debug production errors.

In Chapter 23, you are introduced to the testing capabilities in Visual Studio 2013. You find out about the various test types, diagnostic test adapters, and tools for working with tests. You also learn about working with test results, ordered tests, and the test settings.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.21.246.223