Print | Contents | Close |

The Visual Studio 2005 Debugger

Learning objective

After completing this topic, you should be able to identify key debugging enhancements in Visual Studio 2005.

1. Enhanced debugging features

Visual Studio 2005 includes enhanced debugging features to enable easy, secure, and flexible debugging of code.

It supports debugging of 32-bit and 64-bit managed and unmanaged applications. It also supports remote debugging of code on any platform compatible with Visual Studio.

Visual Studio 2005 uses the new Microsoft Build Engine (MSBuild) as its build system. This system differs from the system used in previous versions of Visual Studio in that it's written using managed code and is built into .NET Framework 2.0. As a result, it no longer requires installation of Visual Studio.

The new build system makes it easier to customize build processes, and to debug code across platforms.

New features of the Visual Studio 2005 debugger that make it easier to debug code include

the Exception Assistant
The Exception Assistant is a new feature for debugging C# applications that has replaced the Exception dialog box in earlier Visual Studio versions. It makes it easier to identify the causes of exceptions in code and to fix them.

When the debugger encounters a runtime exception, the Exception Assistant indicates the possible cause of the exception. It provides a link to online help specific to the type of the exception, as well as a link to a facility for searching general online help about exceptions. It also displays actions you can perform – such as viewing additional details of an exception or enabling code editing – as links.
the Edit and Continue feature
The Edit and Continue feature enables you to modify source code while in break mode and then to resume the debugging process. This makes it unnecessary to stop the debugger, recompile a program, and then rerun its code whenever you make an alteration. However, you shouldn't generally use this feature to modify declaration statements.

To enter break mode so that you can alter code, you can

  • set a breakpoint simply by clicking in the left-hand margin at the appropriate line in code, prior to debugging it
  • start debugging and then select Debug - Break All
  • click the Enable Editing link in the Exception Assistant when an exception occurs
the Just My Code feature
The Just My Code feature simplifies debugging by enabling you to set the debugger to show only user-created code. It hides non-user code – such as types and members provided by Visual Studio – unless the debugger identifies an error in this code.

Although the feature distinguishes between user and system-created code automatically, you can use the following attributes to specify how the debugger must treat specific code:

  • DebuggerNonUserCodeAttribute – to identify system-created code that the debugger must step through
  • DebuggerStepThroughAttribute – to identify code that the debugger must step through, but that may contain breakpoints
  • DebuggerHiddenAttribute – to hide code from the debugger completely, even when the Just My Code feature is disabled
tracepoints
Visual Studio 2005 introduces the use of tracepoints. You can include tracepoints in code in much the same way that you include breakpoints. Instead of breaking code execution, however, a tracepoint causes an associated action of your choice to execute. The action could be to make a calculation, or run a smaller external program simultaneously, or others.

You can use tracepoints and the Trace feature for similar purposes, but tracepoints don't require that you make changes to the source code. Tracepoints run only under the debugger.
support for multiprocess debugging
Visual Studio 2005 enables you to attach the debugger to multiple processes – including processes that run remotely. However, only one of these processes may be active at one time. Once you've attached the debugger to multiple processes, you can select the process you wish to debug to make it active.
simplified system for remote debugging
Visual Studio 2005 provides a secure and robust remote debugging feature with a simple setup process.

To set up remote debugging, you

  • install Visual Studio 2005 on the host machine and its Remote Debugging components on the remote machine
  • install the application and related files on the remote machine via the Build Events project property settings in Visual Studio 2005
  • from the host machine, attach to the remote process you want to debug

Question

Suppose you want to prevent the Visual Studio 2005 debugger from displaying a section of code which you already know functions correctly. To do this, you've already enabled the Just My Code debugging feature. You then need to define the code as system – rather than user-created – code.

Which attribute do you use to do this?

Options:

  1. DebuggerHiddenAttribute
  2. DebuggerNonUserCodeAttribute
  3. DebuggerStepThroughAttribute

Answer

You use DebuggerNonUserCodeAttribute to identify system code, which won't display if the Just My Code feature is enabled.

Option 1 is incorrect. You use DebuggerHiddenAttribute to identify code that must be hidden from the debugger, even if the Just My Code feature is disabled.

Option 2 is correct. You use DebuggerNonUserCodeAttribute to identify system-created code. With the Just My Code feature enabled, the debugger will step through this code rather than displaying it, unless the code contains an error it detects.

Option 3 is incorrect. You use DebuggerStepThroughAttribute to identify code that the debugger must step through, but that may include breakpoints. This attribute doesn't specifically identify the code as non-user code.

Suppose an application you're designing includes a dialog box that contains a Calculate button. To debug the code for the button in Visual Studio 2005, you simply start debugging and then click the button you want to test. The Exception Assistant will then alert you to any errors in the code.

  public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
int a;
int b;
int c;
a = 5;
b = 0;
c = a / b;
}
}
}

First you start the debugging process from the code window.

  public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
int a;
int b;
int c;
a = 5;
b = 0;
c = a / b;
}
}
}

You select Debug - Start Debugging.

Alternatively, you press Alt+D, S.

The debugging process opens the dialog box that you've designed the source code to create.

To check the code for the Calculate button, you click this button.

The debugger checks the code for the button. When an exception occurs, the Exception Assistant highlights the cause of the problem in the script and provides information about the exception. You can now alter the script to fix the problem and try debugging again.

    private void button1_Click(object sender, EventArgs e)
{
int a;
int b;
int c;
a = 5;
b = 0;
c = a / b;
}
}
}

Now suppose you need to be able to alter the value specified in a line of code when you debug the code. To enable you to do this, you've added a breakpoint to the appropriate line.

  public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
//Application.EnableVisualStyles()
Employee e1 = new Employee("Ben Stiller", 57000);
Employee e2 = new Employee("Big Foot", 90000);
Employee e3 = new Employee("Tucan Sam", 87000);
}
}
}

You begin debugging the code by clicking the Play button on the toolbar.

The debugger advances through the code until it reaches the breakpoint, which pauses execution.

You can now select the code you want to change and then alter it, before resuming the debugging process.

    {
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
//Application.EnableVisualStyles()
Employee e1 = new Employee("Ben Stiller", 57000);
Employee e2 = new Employee("Big Foot", 90000);
Employee e3 = new Employee("Tucan Sam", 87000);
}
}
}

You select 90000 in the code, type 85000 to replace this value, and click the Play button on the toolbar to resume debugging.

Debugging of the code, which now includes the changes you've made, continues until a new breakpoint is encountered.

    {
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
//Application.EnableVisualStyles()
Employee e1 = new Employee("Ben Stiller", 57000);
Employee e2 = new Employee("Big Foot", 85000);
Employee e3 = new Employee("Tucan Sam", 87000);
}
}
}

The process completes without any errors, and Visual Studio 2005 opens the form you created for the code. You have now used the Edit and Continue feature to modify code without having to exit the debugging process.

Next suppose the values in your source code must depend on the result of another process. You therefore want to attach the other process to the debugger for the application.

  public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
//Application.EnableVisualStyles()
Employee e1 = new Employee("Ben Stiller", 57000);
Employee e2 = new Employee("Big Foot", 85000);
Employee e3 = new Employee("Tucan Sam", 87000);
}
}
}

You select Debug - Attach to Process.

Alternatively, you press Alt+D, P.

The Attach to Process dialog box lists available processes you can set the debugger to attach to the source code.

You select the required process and click Attach.

This returns you to the source code.

  public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
//Application.EnableVisualStyles()
Employee e1 = new Employee("Ben Stiller", 57000);
Employee e2 = new Employee("Big Foot", 85000);
Employee e3 = new Employee("Tucan Sam", 87000);
}
}
}

You continue debugging the active application, and it pauses at the breakpoint in the script. You now want to check for processes to which the application is attached.

  public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
//Application.EnableVisualStyles()
Employee e1 = new Employee("Ben Stiller", 57000);
Employee e2 = new Employee("Big Foot", 85000);
Employee e3 = new Employee("Tucan Sam", 87000);
}
}
}

You select Debug - Windows - Processes.

Alternatively, you press Alt+D, W, P.

The Processes window now lists details of the processes attached to the application.

Using the icons in this window, you can set the active process, detach processes, or break execution of a process for debugging.

To set the debugger windows to show only user-created code, you first select Tools - Options to open the Options dialog box.

The Options dialog box includes a tree pane, which enables you to access option settings in different categories. A settings pane displays settings in the selected category.

You scroll down, access general debugging settings, and then enable the Just My Code feature.

You expand the Debugging node, select General, and then select the Enable Just My Code checkbox from the list of general debugging options that displays in the settings pane, and click OK.

You have now enabled the Just My Code feature. During debugging, debugging windows will now display only user-created code.

Question

You are running a program that organizes quarterly sales figures for January through April. You want to attach the program to another managed process, named validate.exe, for validation purposes.

How do you attach the program to the validate.exe process and then open the Process window to check that the attachment succeeded?

Options:

  1. Select Debug - Attach to Process, select validate.exe, click the Attach button, and select Debug - Windows - Processes
  2. Select Debug - Windows - Processes, select validate.exe, and click the Attach button
  3. Select Debug - Attach to Process, select validate.exe, and select Debug - Windows - Processes

Answer

To attach the process and then open the Process window to verify the attachment, you select Debug - Attach to Process, select validate.exe from the Available Processes list, click the Attach button, and select Debug - Windows - Processes.

Alternatively, you press Alt+D, P to open the Attach to Process dialog box and Alt+D, W, P to open the Process window.

2. Creating visualizers

Visualizers provide a new way of exploring what particular variables contain by creating a more appropriate interface. They provide a type-specific alternate view of objects or variables, based on their data type, and allow the user to interact with the Debugger. Visual Studio 2005 has four new standard visualizers – a DataSet visualizer that shows DataSets in a grid, an XML visualizer, a text visualizer, and an HTML visualizer.

The XML, HTML, and text visualizers refer to string variables. If a string supports multiple visualizers, you can select which to use.

In addition to providing standard visualizers, Visual Studio 2005 enables you to create your own, custom visualizers.

To do this, you need to

The code for a visualizer you create needs to be in the form of a DLL file so that the debugger can read it. So to begin, you create a new C# class library project, in this case named MyVisualizer2. The Class1.cs page for the new project opens automatically.

using System;
using System.Collections.Generic;
using System.Text;

namespace MyVisualizer2
{
public class Class1
{
}
}

Using the Solution Explorer, you rename the Class1.cs file as DebugSide.cs.

Next you need to create a reference to the Microsoft.VisualStudio.DebuggerVisualizers.DLL file, so that you can use the classes defined in it. To access the References folder for the project, however, you first need to set the Solution Explorer to list all of the project's components.

You click the Show All icon.

All files and folders for the project, including a References folder, are now listed.

To begin creating the required reference, you right-click the References folder and select Add Reference.

In the Add Reference dialog box, you scroll down the list of component names, select Microsoft.VisualStudio.DebuggerVisualizers.DLL, and click OK.

This adds the reference to the expanded References folder.

You then use a using statement to import the reference into your code.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualStudio.DebuggerVisualizers;

namespace MyVisualizer2
{
public class DebugSide
{
}
}

Next you specify the base class – in this case DialogDebuggerVisualizer – from which the DebugSide class you've created must inherit methods.

You then override the Show method for the DialogDebuggerVisualizer class, and add the required Show method for the visualizer you're creating. This method creates the visualizer interface and enables it to display information.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualStudio.DebuggerVisualizers;

namespace MyVisualizer2
{
public class DebugSide : DialogDebuggerVisualizer
{
protected override void Show(
IDialogVisualizerService windowService,
IVisualizerObjectProvider objectProvider) { }
}
}

You now need to create the dialog box in which the visualizer will display data. You decide to use a Windows Forms message box for this purpose, so you need to create a reference to the System.Windows.Forms class. To enable you to do this, you open the Add Reference dialog box using the Solution Explorer.

You add the System.Windows.Forms reference to the References folder in the Solution Explorer.

You select System.Windows.Forms and click OK.

You have successfully added the System.Windows.Forms reference to the References folder.

You use a using statement to import the reference in the code.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualStudio.DebuggerVisualizers;
using System.Windows.Forms;

namespace MyVisualizer2
{
public class DebugSide : DialogDebuggerVisualizer
{
protected override void Show(
IDialogVisualizerService windowService,
IVisualizerObjectProvider objectProvider) { }
}
}

You now need to add code to tell Visual Studio how you want the interface for the visualizer to look and act. To do this, you use a MessageBox.Show method.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualStudio.DebuggerVisualizers;
using System.Windows.Forms;

namespace MyVisualizer2
{
public class DebugSide : DialogDebuggerVisualizer
{
protected override void Show(
IDialogVisualizerService windowService,
IVisualizerObjectProvider objectProvider)
{
MessageBox.Show(objectProvider.GetObject().ToString());
}
}
}

To check for any build errors in the code you've written, you select Build - Build MyVisualizer2.

No build errors occurred, and you can now return to the code. You need to add code that will tell the debugger side – the side where users work – which classes make up the visualizer.

To inform Visual Studio of the classes your visualizer will use and identify their source, you add an Assembly attribute prior to the DebugSide class definition.

using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.VisualStudio.DebuggerVisualizers;
using System.Windows.Forms;
[assembly: System.Diagnostics.DebuggerVisualizer(
typeof(MyVisualizer2.DebugSide),
typeof(VisualizerObjectSource),
Target=typeof(System.String),
Description="My First Visualizer")]
namespace MyVisualizer2
{
public class DebugSide : DialogDebuggerVisualizer
{
protected override void Show(
IDialogVisualizerService windowService,
IVisualizerObjectProvider objectProvider)
{
MessageBox.Show(objectProvider.GetObject().ToString());
}
}
}

You have now created a visualizer, which you can test and then install in Visual Studio 2005.

Question

Suppose you want to create a custom visualizer in Visual Studio 2005.

Place the steps you perform to do this in the correct order.

Options
Option Description
AIdentify the debugger-side classes that the visualizer must use
BOpen a new class library project file
CReference Microsoft.VisualStudio.DebuggerVisualizers.DLL
DSet debugger-side code to inherit from the DialogDebuggerVisualizer base class
EUse a Show method to specify how the visualizer must display

Answer

Correct ranking
Option Description
BOpen a new class library project file
To read the code for a visualizer, the debugger requires that it be stored in a DLL file. To create a visualizer, you therefore start by creating a class library project file, which uses this format.
CReference Microsoft.VisualStudio.DebuggerVisualizers.DLL
Once you've opened a new class library project file, you create a reference to Microsoft.VisualStudio.DebuggerVisualizers.DLL and import the reference, so that the visualizer you create can use the classes it contains.
DSet debugger-side code to inherit from the DialogDebuggerVisualizer base class
Once you've referenced Microsoft.VisualStudio.DebuggerVisualizers.DLL, you need to specify the base class from which the visualizer you're creating must inherit methods and properties.
EUse a Show method to specify how the visualizer must display
After referencing the required classes, you override the Show method in the base class and then add a new Show method to specify how the user interface for the new visualizer must display.
AIdentify the debugger-side classes that the visualizer must use
Finally, you need to specify which classes – in addition to the base class you've already referenced – the debugger side of the visualizer you're creating must use. Once you've done this, you can create a test harness and then test the visualizer before installing it in Visual Studio 2005.

3. Using the DataTips feature

The DataTips feature in Visual Studio 2005 now provides a view of important properties and attributes while in break mode. You can view and edit these properties and attributes using the source editor in which you type your code.

You can't, however, edit read-only files using the DataTips feature.

Suppose you have an application in break mode and you want to use the DataTips feature to

check the type of visualizer being used for an entryedit a value

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
//Application.EnableVisualStyles()
Employee e1 = new Employee("Ben Stiller", 57000);
Employee e2 = new Employee("Big Foot", 85000);
Employee e3 = new Employee("Tucan Sam", 87000);
}
}
}

You decide to check the e1 variable in the code. You hover your cursor over e1, and a small DataTip displays.

When you move your cursor over the + (plus sign) icon, an extension of the entry displays to list the attributes of the e1 code item.

You now want to check the visualizer that the code Ben Stoller is using.

  public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
//Application.EnableVisualStyles()
Employee e1 = new Employee("Ben Stiller", 57000);
Employee e2 = new Employee("Big Foot", 85000);
Employee e3 = new Employee("Tucan Sam", 87000);
}
}
}

You click the magnifying glass icon alongside the name entry in the DataTip, and a drop-down list of visualizers displays. A tick indicates the visualizer currently in use.

If the entry had been using the incorrect visualizer, you could have changed it easily by selecting the correct visualizer.

Next you want to use the DataTip to change the salary value assigned to the e1 variable from 57,000 to 90,000. To do this, you simply select the salary value in the DataTip and then type the new, required value.

  public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
//Application.EnableVisualStyles()
Employee e1 = new Employee("Ben Stiller", 57000);
Employee e2 = new Employee("Big Foot", 85000);
Employee e3 = new Employee("Tucan Sam", 87000);
}
}
}

You type 90000.

You have now successfully used the new extended DataTips feature to edit an entry's attributes while in break mode.

  public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
//Application.EnableVisualStyles()
Employee e1 = new Employee("Ben Stiller", 57000);
Employee e2 = new Employee("Big Foot", 85000);
Employee e3 = new Employee("Tucan Sam", 87000);
}
}
}

Question

While in break mode, you decide to edit multiple entries using the extended DataTips feature. However, entries you select don't have extended DataTips associated with them.

Why would some entries not have extended DataTips?

Options:

  1. The entries are in the wrong file format
  2. The entries are using the wrong visualizer
  3. The entries occur in a read-only file
  4. The entries may not be complex

Answer

To use the extended DataTips feature on a data type, the data type must be complex and cannot be read-only.

Option 1 is incorrect. Complex data entries aren't separate files but object types of data with multiple properties and attributes.

Option 2 is incorrect. Visualizers provide a type-specific alternate view of objects or variables, based on their data type. However, the visualizer that an entry uses doesn't affect the DataTips feature.

Option 3 is correct. You cannot use the extended DataTips feature to edit files that are read-only.

Option 4 is correct. You can edit only complex data types – types with multiple properties – using the DataTips feature.

Question

Suppose you want to change the price property of the p1 variable, which represents a complex data type, to 75.

What steps do you perform to do this?

Options:

  1. Click the + sign, click the price entry, type 75, and press Enter twice
  2. Click the + sign, click the price entry, and type 75
  3. Click the magnifying glass icon, click the price entry, type 75, and press Enter twice

Answer

To change the price value for the p1 DataTip, you click the + sign, click the price entry, type 75, and press Enter twice.

4. Setting debugger display attributes

Debugger display attributes enable you to specify what a type you've created will look like when displayed in a debugger.

A type class represents type declarations, and is the primary way to access metadata. You use the members of a type to find information about a type declaration. A type is an abstract base class that allows multiple implementations.

C# 2005 offers three attributes that you can use to alter how a type displays:

The DebuggerDisplay attribute resides in the System.Diagnostics namespace, and can be used to control how a type or member is displayed in the debugger variable windows. It is applied at class level and the members can be private or public.

The DebuggerDisplay constructor only has a single argument – a string that is displayed in the value column when the type occurs.

The string can contain brackets – round or curly – and the text within a pair is assumed to be the name of a property, method, or field. It is evaluated as an expression.

Suppose you want to structure the DebuggerDisplay attribute so that you can examine numerator and denominator properties. To do this, you reference the attribute in the code.

  [MISSING CODE("Value = {Numerator} / {Denominator}")]
class Fraction
{
private int m_Numerator;
private int m_Denominator;

public int Numerator
{
get
{
return m_Numerator;
}
set
{
m_Numerator = value;
}
}
public int Denominator
{
get
{
return m_Denominator;
}
set
{
m_Denominator = value;

You type DebuggerDisplay to complete the code.

You have set DebuggerDisplay attribute for the Fraction class.

  [DebuggerDisplay("Value = {Numerator} / {Denominator}")]
class Fraction
{
private int m_Numerator;
private int m_Denominator;

public int Numerator
{
get
{
return m_Numerator;
}
set
{
m_Numerator = value;
}
}
public int Denominator
{
get
{
return m_Denominator;
}
set
{
m_Denominator = value;

When you debug instances of the class, the DebuggerDisplay attribute determines the output shown in the Watch window and when the mouse is hovered over instances. In this case, you have used the attribute to reveal the values of the testfraction type's properties.

public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void Form1_Load(object sender, EventArgs e)
{
Fraction testfraction = new Fraction();
testfraction.Denominator = 20;
testfraction.Numerator = 5;
}
}

Supplement

Selecting the link title opens the resource in a new browser window.

Code window

View a full example of code that uses the DebuggerDisplay attribute.

The DebuggerTypeProxy attribute is similar to the DebuggerDisplay attribute but enables you to change the view of the type without changing the type itself. To do this, you specify a display proxy to use when debugging the type.

The input parameter for the DebuggerTypeProxy constructor specifies the proxy to use.


[DebuggerTypeProxy(typeof(Fraction.Check))]
public class Fraction
{
private int m_Numerator;
private int m_Denominator;
public int Numerator
{
get
{
return m_Numerator;
}
set
{
m_Numerator = value;
}
}
public int Denominator
{
get
{
return m_Denominator;
}
set
{
m_Denominator = value;
}

The debugger variable window displays only the public members of the DebuggerTypeProxy proxy class.

    private void Form1_Load(object sender, EventArgs e)
{
Fraction testfraction = new Fraction();
testfraction.Denominator = 20;
testfraction.Numerator = 5;
}
}
}

The DebuggerTypeProxy attribute can be used at the assembly level. At this level, you use its Target property to specify the type to which the proxy must apply.

Supplement

Selecting the link title opens the resource in a new browser window.

Code window

View a full example of code that uses the DebuggerTypeProxy attribute.

If a field or property is to be displayed in the Debugger variable windows, the DebuggerBrowsable attribute is used to determine how it will appear.

The DebuggerBrowsableState enumeration is used when utilizing this attribute, which has the following values:

Never, meaning the field or property the attribute is applied to is not displayed.

Collapsed, meaning the field or property the attribute is applied to is shown in a minimized display

RootHidden, meaning only the child objects of the field or property the attribute is applied to are shown.

using System.Collections
public class AttClass
{

[DebuggerBrowsable(DebuggerBrowsableState.Never)]
public int myInt = 5;

[DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
public Stack myFirstStack;

[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
public Stack mySecondStack;
//...
}

Question

While working in Visual Studio 2005, you decide to change how the application displays a type, but without changing the characteristics of the type itself.

Which attribute do you use to do this?

Options:

  1. DebuggerDisplay
  2. DebuggerHidden
  3. DebuggerStepThrough
  4. DebuggerTypeProxy

Answer

You use the DebuggerTypeProxy attribute to change the display properties of a type, without changing the type itself.

Option 1 is incorrect. The DebuggerDisplay determines how a type or member is displayed in the debugger variable window. The constructor contains a single argument in the form of a string, and the text within the string is assumed to be the instance name of the type.

Option 2 is incorrect. The DebuggerHidden attribute is used to hide code from the debugger, even when the Just My Code feature is disabled.

Option 3 is incorrect. You would use the DebuggerStepThrough attribute to tell the debugger to step through certain code to the next set of code relevant to you.

Option 4 is correct. The DebuggerTypeProxy attribute enables you to change the view for a type by specifying its display proxy, without altering the type in any way.

Summary

Enhanced debugging features of Visual Studio 2005 include the Exception Assistant, the Edit and Continue feature, the Just My Code feature, the introduction of tracepoints, and support for multiprocess debugging.

Visual Studio 2005 provides four new standard visualizers – a DataSet visualizer that shows DataSets in a grid, an XML visualizer, a text visualizer, and an HTML visualizer. It also enables you to create custom visualizers.

The extended DataTips feature enables you to edit the properties of complex data types while in break mode.

Debugger display attributes – DebuggerDisplay, DebuggerTypeProxy and DebuggerBrowsable – enable you to specify how the debugger variable windows must display types.