Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visual Studio 2013 C++: STL container's elements display in debugger

MSVS 2013 during C++ debugging (Autos and Watch windows) shows only size of STL container's:

MSVS 2010: "[9](9,8,7,6,5,4,3,2,1)"
MSVS 2013: "{ size=9 }"

Line expand is required to see element's value in MSVS 2013.
Is there any way to make MSVS 2013 show STL containers like MSVS 2010 in debugger?
I tried to remove stl.natvis (it is used in 2013), but it doesn't help: autoexp.dat is still not used.
Is possible to force MSVS 2013 use autoexp.dat?
Is it possible to modify stl.natvis scripts (construct DisplayString from container element's values)?
Any other way?

like image 201
DmitriyH Avatar asked Dec 28 '13 21:12

DmitriyH


4 Answers

FYI, to use autoexp.dat in VS2015 set "Use Native Compatibility Mode" under

Options > Debugging > General

like image 163
Chris81 Avatar answered Nov 03 '22 10:11

Chris81


As a partial solution you can add multiple conditional DisplayString elements to each container type's information in a .natvis file.

The limitation to this is that you can specify that elements only up to some fixed maximum be displayed in the DisplayString debugger output (however, all elements are still displayed in the expansion area that you get when clicking on the variable's + sign in the debugger display).

As an example, drop this into a file named %USERPROFILE%\My Documents\Visual Studio 2013\Visualizers\custom.stl.natvis:

<?xml version="1.0" encoding="utf-8"?>
<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">

<Type Name="std::vector&lt;*&gt;">
    <DisplayString Condition="(_Mylast - _Myfirst) >  3">[{_Mylast - _Myfirst}] ({_Myfirst[0]}, {_Myfirst[1]}, {_Myfirst[2]}, ...)</DisplayString>
    <DisplayString Condition="(_Mylast - _Myfirst) == 3">[{_Mylast - _Myfirst}] ({_Myfirst[0]}, {_Myfirst[1]}, {_Myfirst[2]})</DisplayString>
    <DisplayString Condition="(_Mylast - _Myfirst) == 2">[{_Mylast - _Myfirst}] ({_Myfirst[0]}, {_Myfirst[1]})</DisplayString>
    <DisplayString Condition="(_Mylast - _Myfirst) == 1">[{_Mylast - _Myfirst}] ({_Myfirst[0]})</DisplayString>
    <DisplayString>{{ size={_Mylast - _Myfirst} }}</DisplayString>
    <Expand>
        <Item Name="[size]">_Mylast - _Myfirst</Item>
        <Item Name="[capacity]">_Myend - _Myfirst</Item>
        <ArrayItems>
            <Size>_Mylast - _Myfirst</Size>
            <ValuePointer>_Myfirst</ValuePointer>
        </ArrayItems>
    </Expand>
</Type>

</AutoVisualizer>

And in your next VS2013 C++ debug session vectors will show up to the first three elements in the debugger's DisplayString output in a format similar to the old autoexp.dat display.

You can make the obvious additional edits to the custom natvis to display more than 3 elements. Unfortunately, you'll need to do something similar for each container type you want displayed this way; probably a good job for an intern.

like image 39
Michael Burr Avatar answered Nov 03 '22 08:11

Michael Burr


I found one way to force MSVS 2012/2013 use autoexp.dat: set "Enable Edit And Continue" and "Enable Native Edit and Continue".
It disables "data viewing enhancements" (natvis) for C++, and elements of std::vector (std::list, std::map, ...) become displayed on the main line of the variable (MSVS 2010 style).
But, it still would be interesting, is it possible to modify stl.natvis to get the same display result?

like image 39
DmitriyH Avatar answered Nov 03 '22 10:11

DmitriyH


Uncheck "Show raw structure of objects in variables windows" in Options > Debugging > General.

like image 41
0xFE Avatar answered Nov 03 '22 10:11

0xFE