c++debuggingvisual-studio-2015natvis

How to visualise a simple std::string with natvis?


I can't have a decent view of a basic std:string in VS2015 while debugging. I followed the instructions given at this address :https://msdn.microsoft.com/fr-fr/library/jj620914.aspx (that is debugger type set to native mode, and uncheck both Use Managed Compatibility Mode and Use Native Compatibility Mode) . I have also added the stl.nativs file to my solution.

Currently my debugger looks like : enter image description here

I would like to see as a value directly "test" for my variable str (instead of a very complex tree). Can you help me with this ?


Solution

  • I find the answer, for a very strange reason the stl.natvis file that I found in my VS Installation directory ( C:\Program Files (x86)\Microsoft Visual Studio 14.0\Common7\Packages\Debugger\Visualizers for me ) and that I have added to my project is not recognised by the debugger automatically.

    So the solution was to add another Debugger visualization file (.natvis) to my solution (right click ->add new item ) and to copy/past the content of the stl.natvis file to this new file. After rebuild, the standard std:string is appropriately displayed by the debugger.

    For completeness, see below the part of the stl.natvis that deals with std::string for visual studio 2015.

    <!-- VC 2015 -->
      <Type Name="std::basic_string&lt;char,*&gt;">
        <DisplayString Condition="_Mypair._Myval2._Myres &lt; _Mypair._Myval2._BUF_SIZE">{_Mypair._Myval2._Bx._Buf,na}</DisplayString>
        <DisplayString Condition="_Mypair._Myval2._Myres &gt;= _Mypair._Myval2._BUF_SIZE">{_Mypair._Myval2._Bx._Ptr,na}</DisplayString>
        <StringView Condition="_Mypair._Myval2._Myres &lt; _Mypair._Myval2._BUF_SIZE">_Mypair._Myval2._Bx._Buf,na</StringView>
        <StringView Condition="_Mypair._Myval2._Myres &gt;= _Mypair._Myval2._BUF_SIZE">_Mypair._Myval2._Bx._Ptr,na</StringView>
        <Expand>
          <Item Name="[size]" ExcludeView="simple">_Mypair._Myval2._Mysize</Item>
          <Item Name="[capacity]" ExcludeView="simple">_Mypair._Myval2._Myres</Item>
          <Item Name="[allocator]" ExcludeView="simple">_Mypair</Item>
          <ArrayItems>
            <Size>_Mypair._Myval2._Mysize</Size>
            <ValuePointer Condition="_Mypair._Myval2._Myres &lt; _Mypair._Myval2._BUF_SIZE">_Mypair._Myval2._Bx._Buf</ValuePointer>
            <ValuePointer Condition="_Mypair._Myval2._Myres &gt;= _Mypair._Myval2._BUF_SIZE">_Mypair._Myval2._Bx._Ptr</ValuePointer>
          </ArrayItems>
        </Expand>
      </Type>
    
      <!-- VC 2015 -->
      <Type Name="std::basic_string&lt;wchar_t,*&gt;">
        <AlternativeType Name="std::basic_string&lt;unsigned short,*&gt;" />
        <AlternativeType Name="std::basic_string&lt;char16_t,*&gt;" />
        <DisplayString Condition="_Mypair._Myval2._Myres &lt; _Mypair._Myval2._BUF_SIZE">{_Mypair._Myval2._Bx._Buf,su}</DisplayString>
        <DisplayString Condition="_Mypair._Myval2._Myres &gt;= _Mypair._Myval2._BUF_SIZE">{_Mypair._Myval2._Bx._Ptr,su}</DisplayString>
        <StringView Condition="_Mypair._Myval2._Myres &lt; _Mypair._Myval2._BUF_SIZE">_Mypair._Myval2._Bx._Buf,su</StringView>
        <StringView Condition="_Mypair._Myval2._Myres &gt;= _Mypair._Myval2._BUF_SIZE">_Mypair._Myval2._Bx._Ptr,su</StringView>
        <Expand>
          <Item Name="[size]" ExcludeView="simple">_Mypair._Myval2._Mysize</Item>
          <Item Name="[capacity]" ExcludeView="simple">_Mypair._Myval2._Myres</Item>
          <Item Name="[allocator]" ExcludeView="simple">_Mypair</Item>
          <ArrayItems>
            <Size>_Mypair._Myval2._Mysize</Size>
            <ValuePointer Condition="_Mypair._Myval2._Myres &lt; _Mypair._Myval2._BUF_SIZE">_Mypair._Myval2._Bx._Buf</ValuePointer>
            <ValuePointer Condition="_Mypair._Myval2._Myres &gt;= _Mypair._Myval2._BUF_SIZE">_Mypair._Myval2._Bx._Ptr</ValuePointer>
          </ArrayItems>
        </Expand>
      </Type>
    
      <Type Name="std::basic_string&lt;char32_t,*&gt;">
        <DisplayString Condition="_Mypair._Myval2._Myres &lt; _Mypair._Myval2._BUF_SIZE">{_Mypair._Myval2._Bx._Buf,s32}</DisplayString>
        <DisplayString Condition="_Mypair._Myval2._Myres &gt;= _Mypair._Myval2._BUF_SIZE">{_Mypair._Myval2._Bx._Ptr,s32}</DisplayString>
        <StringView Condition="_Mypair._Myval2._Myres &lt; _Mypair._Myval2._BUF_SIZE">_Mypair._Myval2._Bx._Buf,s32</StringView>
        <StringView Condition="_Mypair._Myval2._Myres &gt;= _Mypair._Myval2._BUF_SIZE">_Mypair._Myval2._Bx._Ptr,s32</StringView>
        <Expand>
          <Item Name="[size]" ExcludeView="simple">_Mypair._Myval2._Mysize</Item>
          <Item Name="[capacity]" ExcludeView="simple">_Mypair._Myval2._Myres</Item>
          <Item Name="[allocator]" ExcludeView="simple">_Mypair</Item>
          <ArrayItems>
            <Size>_Mypair._Myval2._Mysize</Size>
            <ValuePointer Condition="_Mypair._Myval2._Myres &lt; _Mypair._Myval2._BUF_SIZE">_Mypair._Myval2._Bx._Buf</ValuePointer>
            <ValuePointer Condition="_Mypair._Myval2._Myres &gt;= _Mypair._Myval2._BUF_SIZE">_Mypair._Myval2._Bx._Ptr</ValuePointer>
          </ArrayItems>
        </Expand>
      </Type>
    

    Edit

    See below the final watch console : (also please note that you should only copy part of the stl.natvis that you want, it seems that a full copy/past does not work.)

    enter image description here