Debugger Type Visualizers for C++ in Visual Studio 2012

 In Visual Studio 2012, one of the new features for C++ developers is the new native type visualization framework (natvis) added to the debugger which allows customizing the way data types are displayed in debugger variable windows (e. g. autos, watch, locals, and data tips). For those who are familiar with the autoexp.dat file that has been used in earlier versions of Visual Studio, this new visualization framework supersedes that and offers xml syntax, better diagnostics, versioning and multiple file support.

To illustrate how type visualizers help make it easier to inspect objects, the following screenshot shows how a std::vector<int> is displayed in the debugger without any type visualizers:

                  

The view without type visualizers is not user-friendly and hard to read. You cannot easily see the size or the elements of the vector. Visual Studio ships with type visualizers for common data types such as std::vector and the default view for a std::vector using type visualizers is much more useful:

 

 

Creating a type visualizer for a custom data type

If you have a custom data type you can easily override Visual Studio’s default view of it using this framework and make it easy to inspect objects of that type. To demonstrate how you can do this, let’s go through the process of creating one for the simple rectangle type shown in the code snippet below (the dummy code that uses it is also included):

struct Rectangle

{

    int height;

    int width;

};

 

int _tmain(int argc, _TCHAR* argv[])

{

    Rectangle myRectangle = { 3, 4 };

    Rectangle myRectangle2 = { 4, 4 };

    return 0;

}

 

The debugger’s default view of the “myRectangle” variable which we are going to customize is as follows:

 

 

Type visualizers for C++ types are specified in .natvis files. A natvis file is simply an xml file (with .natvis extension) that contains visualization rules for one or more types. At the start of each debugging session, Visual Studio processes any natvis files it can find in the following locations:

  • -         %VSINSTALLDIR%\Common7\Packages\Debugger\Visualizers (requires admin access)
  • -         %USERPROFILE%\My Documents\Visual Studio 2012\Visualizers\
  • -         VS extension folders

 

As the first visualizer for the rectangle type, create a new file called “rectangle.natvis” containing the following xml (explained further below) and save it in “My Documents\Visual Studio 2012\Visualizers” folder.

 

<?xml version=1.0 encoding=utf-8?>

<AutoVisualizer xmlns=http://schemas.microsoft.com/vstudio/debugger/natvis/2010>

    <Type Name=Rectangle>

        <DisplayString>A rectangle with height = {height} and width = {width}</DisplayString>

    </Type>

</AutoVisualizer>

 

After the file is saved, start debugging the code snippet we have for the type and view the ‘myRectangle’ variable in the watch window. The debugger now displays the object as:

 

 

 

To explain the xml snippet in the natvis file, each Type element represents a visualizer entry for a type whose fully qualified name is specified in the Name attribute. DisplayString element customizes the string shown in the value column for the type. It accepts a mixture of arbitrary strings and expressions. Everything inside curly braces ({height}, {width} above) is interpreted as an expression and gets evaluated by the debugger.

Let’s assume you would like to enhance this view when the rectangle is actually a square and display something different. You can use the Condition attribute, which is available for many visualizer elements, to have if-else logic in the visualization entry. Add the following highlighted line to the visualizer entry and save the file:

<?xml version=1.0 encoding=utf-8?>

<AutoVisualizer xmlns=http://schemas.microsoft.com/vstudio/debugger/natvis/2010>

    <Type Name=Rectangle>

        <DisplayString Condition=height == width>This is a square with sides of {height}</DisplayString>

        <DisplayString>This is a rectangle with height = {height} and width = {width}</DisplayString>

    </Type>

</AutoVisualizer>

 

Note that it is NOT necessary to restart Visual Studio for it to pick up the changes to a visualizer. Once you start the debugger and add ‘myRectangle’, ‘myRectangle2’ variables to the watch window, you can see a different string is shown for a rectangle object that is actually a square:

 

 

Just as you can customize the value of the variable shown in the value column, you can also customize the view of the child elements when the variable is expanded in the debugger windows. Let’s say you would like to see the area of a rectangle in addition to its height and width during debugging. The Expand node, which allows you to define child elements for a type, can be used for this purpose. Add the highlighted section below to the visualizer entry and save the file:

<?xml version=1.0 encoding=utf-8?>

<AutoVisualizer xmlns=http://schemas.microsoft.com/vstudio/debugger/natvis/2010>

    <Type Name=Rectangle>

        <DisplayString Condition=height == width>A square with sides of {height}</DisplayString>

        <DisplayString>A rectangle with height = {height} and width = {width}</DisplayString>

        <Expand>

            <Item Name=height>height</Item>

            <Item Name=width>width</Item>

            <Item Name=area>height * width</Item>

        </Expand>

    </Type>

</AutoVisualizer>

 

As you can guess, each Item node defines a single child element whose name is given by the Name attribute and whose value is given by the expression in the node text. This is the updated view with the area element added:

 

More information

This blog post covers just a little bit of what you can do with the new native type visualization framework in the Visual Studio debugger. To learn more about it you can check out our sample page on msdn where we have more examples, xml syntax reference, instructions on turning on diagnostics and deploying visualizers via VSIX packages.

 

 

Cagri Aslan, Developer on the Visual Studio Debugger team.