STL and WinDbg

Some applications are written using Standard Template Library and it is good that there is !stl WinDbg extension which works with a few types from Plauger’s STL implementation used in Visual C++ CRT library:

0:000> !stl
!stl [options] <varname>
  stl [options] <varname> - dumps an STL variable
  stl [options] -n <type-name> <address>
             currently works with string, wstring
             vector<string>, vector<wstring>
             list<string>, vector<wstring>
             (and pointer varieties therein)
   [options]
       -n <type-name> The name of the type. If the
               type has spaces, surround with
               parentheses ().
       -v      verbose output
       -V      extremely verbose output

If we have public symbols and know variable names we can simply dump their values, for example:

0:000> dv /i /V
prv local  @ecx @ecx            this = 0x0012fbdc
prv local  0012fbf8 @ebp-0x2c   MyName = class std::basic_string<char,std::char_traits<char>,std::allocator<char> >

0:000> !stl MyName
[da 0x12fbfc]
0012fbfc  "COMPANY__NAME"

We can also supply full STL type name:

0:000> !stl -n (std::basic_string<char,std::char_traits<char>,std::allocator<char> >) 0012fbf8
[da 0x12fbfc]
0012fbfc  "COMPANY__NAME"

Let’s dump this string type internal structure to be able to recognize it later in raw data:

0:000> dt -r -n std::basic_string<char,std::char_traits<char>,std::allocator<char> > 0012fbf8
application!std::basic_string<char,std::char_traits<char>,std::allocator<char> >
   +0x000 _Alval           : std::allocator<char>
   =00400000 npos             : 0x905a4d
   +0×004 _Bx              : std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Bxty
      +0×000 _Buf             : [16]  “COMPANY__NAME”

      +0×000 _Ptr             : 0×43415250  “”
   +0×014 _Mysize          : 0xd
   +0×018 _Myres           : 0xf

We see that for short strings less than 16 bytes std::basic_string<char> data starts from offset +4 and followed by the actual string size and its reserved size:

0:000> dd 0012fbf8
0012fbf8  00000000 43415250 45434954 53504d5f
0012fc08  41bf00
33 0000000d 0000000f 41bf3b72
0012fc18  0012fc6c 0046107b 00000000 0012fc78
0012fc28  0041a441 00000000 41bf3b2e 00ed6380
0012fc38  00000003 00ed6128 00ed6128 00f41b00
0012fc48  00ed6128 41bf3b3e 0012fc3c 00000000
0012fc58  0000000f 00f41b98 00f469a0 00000000
0012fc68  014487c8 0012fcfc 00463fdd 00000002

For bigger strings implementation starts with a pointer from offset +4 to the actual string data and then followed by 12 bytes of garbage and then by the actual string size and its reserved size:

0:000> dt -r -n std::basic_string<char,std::char_traits<char>,std::allocator<char> >
application!std::basic_string<char,std::char_traits<char>,std::allocator<char> >
   +0x000 _Alval           : std::allocator<char>
   =00400000 npos             : Uint4B
   +0×004 _Bx              : std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Bxty
      +0×000 _Buf             : [16] Char
      +0×000 _Ptr             : Ptr32 Char
   +0×014 _Mysize          : Uint4B
   +0×018 _Myres           : Uint4B

0:000> dt -r -n std::basic_string<char,std::char_traits<char>,std::allocator<char> > 0012ff08
application!std::basic_string<char,std::char_traits<char>,std::allocator<char> >
   +0x000 _Alval           : std::allocator<char>
   =00400000 npos             : 0x905a4d
   +0×004 _Bx              : std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Bxty
      +0×000 _Buf             : [16]  “???”
      +0×000 _Ptr             : 0×00ed4ba0  “/h /c:100 /enum”
   +0×014 _Mysize          : 0×10
   +0×018 _Myres           : 0×1f

In such cases dpa or dpu commands help to show this additional dereference:

0:000> dpa 0012ff08
0012ff08  00ed2f90 "."
0012ff0c  00ed4ba0 “/h /c:100 /enum”
0012ff10  41eafd01
0012ff14  0012ffc0 “…”
0012ff18  0045890a “……U..SVWUj”

0012ff1c  00000010
0012ff20  0000001f

0012ff24  41bf3996
0012ff28  0012ffc0 “…”
0012ff2c  0044b528 “.E..}.”
0012ff30  00400000 “MZ.”

SDbgExt has commands to interrogate additional STL types.  

- Dmitry Vostokov @ DumpAnalysis.org -

5 Responses to “STL and WinDbg”

  1. Narasimha Vedala Says:

    Nice. I’m aware of it now :)

    Unfortunately I cannot buy your Anthology from Lulu. They don’t ship outside US I believe. Amazon is the way to go now.

  2. Dmitry Vostokov Says:

    Lulu ships to 100 countries I believe. Certainly it ships to Ireland where I live :-) Anyway paperback is available on Amazon and hardback will be available there too in 2 weeks or so. Thanks for your interest in the book!

  3. Narasimha Vedala Says:

    I’ve been following your blog for eons. Be assured, there will be atleast one buyer for all your books; me ;)

    You know, Nostradamus’ prophecy has come true: “A man will rise; he will spread knowledge on how to salvage from a crash; he will bring great force to establishment called tittrix or asstrix or citrix, whichever comes last; Some call him god; others call him windbag freak.”

  4. Dmitry Vostokov Says:

    I didn’t imagine in August 2006 that it would go that far :-)

  5. Dmitry Vostokov Says:

    !std_map is another extension for std::map

Leave a Reply

You must be logged in to post a comment.