<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  version="2.0">
  <channel>
    <title>Saving Private Bytes</title>
    <atom:link
      href="https://docs.microsoft.com/archive/blogs/ambrosew/feed.xml"
      rel="self"
      type="application/rss+xml" />
    <link>https://docs.microsoft.com/archive/blogs/ambrosew/feed.xml</link>
    <description>Bitbucket from Real World Encounters</description>
    <lastBuildDate>Wed, 17 Apr 2019 03:39:51 GMT</lastBuildDate>
    <language>en-US</language>
    <sy:updatePeriod>hourly</sy:updatePeriod>
    <sy:updateFrequency>1</sy:updateFrequency>
    <item>
      <title>Debugging STL Containers with WinDbg Part 4: Pair</title>
      <link>https://docs.microsoft.com/archive/blogs/ambrosew/debugging-stl-containers-with-windbg-part-4-pair</link>
      <pubDate>Fri, 18 Jan 2013 04:12:01 GMT</pubDate>
      <dc:creator><![CDATA[ambrosew]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ambrosew/2013/01/18/debugging-stl-containers-with-windbg-part-4-pair/</guid>
      <description><![CDATA[For previous posts of this series, check out the following links:  Debugging STL Containers with...]]></description>
      <content:encoded><![CDATA[<p>For previous posts of this series, check out the following links:</p>  <p><a href="http://blogs.msdn.com/b/ambrosew/archive/2013/01/14/debugging-stl-containers-with-windbg-prolog.aspx">Debugging STL Containers with WinDbg: Prolog</a>     <br /><a href="http://blogs.msdn.com/b/ambrosew/archive/2013/01/18/debugging-stl-containers-with-windbg-prolog-2.aspx">Debugging STL Containers with WinDbg: Prolog 2</a>     <br /><a href="http://blogs.msdn.com/b/ambrosew/archive/2013/01/15/debugging-stl-containers-with-windbg-part-1-vector.aspx">Debugging STL Containers with WinDbg Part 1: Vector</a>     <br /><a href="http://blogs.msdn.com/b/ambrosew/archive/2013/01/15/debugging-stl-containers-with-windbg-part-2-list.aspx">Debugging STL Containers with WinDbg Part 2: List</a>     <br /><a href="http://blogs.msdn.com/b/ambrosew/archive/2013/01/15/debugging-stl-containers-with-windbg-part-3-map.aspx">Debugging STL Containers with WinDbg Part 3: Map</a></p>  <p>I should’ve blogged this post before <a href="http://blogs.msdn.com/b/ambrosew/archive/2013/01/15/debugging-stl-containers-with-windbg-part-3-map.aspx">part 3</a> as maps use pair to store each tree node’s value, but then I originally intended to fire and forget, so bare with me for now.</p>  <p>A <a href="http://www.bing.com/search?q=stl+pair+site%3Amsdn.microsoft.com">pair</a> is a template class that wraps a pair of values. Simply, pair::first stores the first value, and pair::second stores the second value.</p>  <p>Take the following example:</p>  <div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: rgb(244, 244, 244);">   <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">C:\Projects\STL&gt;type pair.cpp<br />#include &lt;iostream&gt;<br />#include &lt;string&gt;<br /><br />using namespace std;<br /><br />int main() {<br />    pair&lt;string, string&gt; mypair(&quot;pair1&quot;, &quot;pair2&quot;);<br />    cout &lt;&lt; &quot;mypair: &quot; &lt;&lt; mypair.first &lt;&lt; &quot; &quot; &lt;&lt; mypair.second &lt;&lt; endl;<br />}<br />C:\Projects\STL&gt;cl /EHsc /nologo /W4 /MTd /Zi pair.cpp<br />pair.cpp<br /><br />C:\Projects\STL&gt;pair<br />mypair: pair1 pair2</pre>
</div>

<p>First you need to look at the type of the values. Do a dt on the pair variable and the debugger should tell you:</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: rgb(244, 244, 244);">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">0:000&gt; <span style="background-color: rgb(255, 255, 0);">dt mypair</span><br />Local var @ 0x32fae0 Type std::pair&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;<br />   +0x000 first            : <span style="background-color: rgb(255, 255, 0);">std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;</span><br />   +0x01c second           : <span style="background-color: rgb(255, 255, 0);">std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;</span><br /></pre>
</div>

<p>In this case since both of my pair values are strings, if you just do a dt -r on the pair variable, you can already see the values:</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: rgb(244, 244, 244);">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">0:000&gt; dt -r mypair<br />Local var @ 0xe7fe6c Type std::pair&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;<br />   +0x000 first            : std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />      +0x000 _Myproxy         : 0x00ff2e68 std::_Container_proxy<br />         +0x000 _Mycont          : 0x00e7fe6c std::_Container_base12<br />         +0x004 _Myfirstiter     : (null) <br />      +0x004 _Bx              : std::_String_val&lt;std::_Simple_types&lt;char&gt; &gt;::_Bxty<br />         +0x000 _Buf             : [16]  <span style="background-color: rgb(255, 255, 0);">&quot;pair1&quot;</span><br />         +0x000 _Ptr             : 0x72696170  &quot;--- memory read error at address 0x72696170 ---&quot;<br />         +0x000 _Alias           : [16]  &quot;pair1&quot;<br />      +0x014 _Mysize          : 5<br />      +0x018 _Myres           : 0xf<br />      =00ce1d0c npos             : 0xffffffff<br />   +0x01c second           : std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />      +0x000 _Myproxy         : 0x00ff2a68 std::_Container_proxy<br />         +0x000 _Mycont          : 0x00e7fe88 std::_Container_base12<br />         +0x004 _Myfirstiter     : (null) <br />      +0x004 _Bx              : std::_String_val&lt;std::_Simple_types&lt;char&gt; &gt;::_Bxty<br />         +0x000 _Buf             : [16]  <span style="background-color: rgb(255, 255, 0);">&quot;pair2&quot;</span><br />         +0x000 _Ptr             : 0x72696170  &quot;--- memory read error at address 0x72696170 ---&quot;<br />         +0x000 _Alias           : [16]  &quot;pair2&quot;<br />      +0x014 _Mysize          : 5<br />      +0x018 _Myres           : 0xf<br />      =00ce1d0c npos             : 0xffffffff</pre>
</div>

<p>You can expand each value individually as well:</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: rgb(244, 244, 244);">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">0:000&gt; <span style="background-color: rgb(255, 255, 0);">dt -r mypair first..</span><br />Local var @ 0xe7fe6c Type std::pair&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;<br />   +0x000 first   : <br />      +0x000 _Myproxy : <br />      +0x004 _Bx     : <br />         +0x000 _Buf    : [16]  &quot;pair1&quot;<br />         +0x000 _Ptr    : 0x72696170  &quot;--- memory read error at address 0x72696170 ---&quot;<br />         +0x000 _Alias  : [16]  &quot;pair1&quot;<br />      +0x014 _Mysize : 5<br />      +0x018 _Myres  : 0xf<br />      =00ce1d0c npos    : 0xffffffff<br /><br />0:000&gt; <span style="background-color: rgb(255, 255, 0);">dt -r mypair second..</span><br />Local var @ 0xe7fe6c Type std::pair&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;<br />   +0x01c second   : <br />      +0x000 _Myproxy : <br />      +0x004 _Bx      : <br />         +0x000 _Buf     : [16]  &quot;pair2&quot;<br />         +0x000 _Ptr     : 0x72696170  &quot;--- memory read error at address 0x72696170 ---&quot;<br />         +0x000 _Alias   : [16]  &quot;pair2&quot;<br />      +0x014 _Mysize  : 5<br />      +0x018 _Myres   : 0xf<br />      =00ce1d0c npos     : 0xffffffff</pre>
</div>

<p>Or you can use the C++ expression evaluator to access _Buf directly:</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: rgb(244, 244, 244);">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">0:000&gt; <span style="background-color: rgb(255, 255, 0);">?? mypair.first._Bx</span><br />union std::_String_val&lt;std::_Simple_types&lt;char&gt; &gt;::_Bxty<br />   +0x000 _Buf             : [16]  &quot;pair1&quot;<br />   +0x000 _Ptr             : 0x72696170  &quot;--- memory read error at address 0x72696170 ---&quot;<br />   +0x000 _Alias           : [16]  &quot;pair1&quot;<br /><br />0:000&gt; <span style="background-color: rgb(255, 255, 0);">?? mypair.second._Bx</span><br />union std::_String_val&lt;std::_Simple_types&lt;char&gt; &gt;::_Bxty<br />   +0x000 _Buf             : [16]  &quot;pair2&quot;<br />   +0x000 _Ptr             : 0x72696170  &quot;--- memory read error at address 0x72696170 ---&quot;<br />   +0x000 _Alias           : [16]  &quot;pair2&quot;</pre>
</div>

<p>Let’s look at a pair of containers with the following example:</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: rgb(244, 244, 244);">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">C:\Projects\STL&gt;type pair.cpp<br />#include &lt;iostream&gt;<br />#include &lt;string&gt;<br />#include &lt;vector&gt;<br />#include &lt;list&gt;<br /><br />using namespace std;<br /><br />int main() {<br />    vector&lt;string&gt; myvector;<br />    myvector.push_back(&quot;1&quot;);<br />    myvector.push_back(&quot;2&quot;);<br />    myvector.push_back(&quot;3&quot;);<br /><br />    list&lt;string&gt; mylist;<br />    mylist.insert(mylist.end(), &quot;one&quot;);<br />    mylist.insert(mylist.end(), &quot;two&quot;);<br />    mylist.insert(mylist.end(), &quot;three&quot;);<br /><br />    pair&lt;vector&lt;string&gt;, list&lt;string&gt;&gt; mypair(myvector, mylist);<br />    cout &lt;&lt; mypair.first[0] &lt;&lt; &quot; &quot; &lt;&lt; mypair.second.front() &lt;&lt; endl;<br />}<br />C:\Projects\STL&gt;cl /EHsc /nologo /W4 /MTd /Zi pair.cpp<br />pair.cpp<br /><br />C:\Projects\STL&gt;pair<br />1 one</pre>
</div>

<p>Again, you need to look at the type of the values. Do a dt on the pair variable and the debugger should tell you:</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: rgb(244, 244, 244);">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">0:000&gt; dt mypair<br />Local var @ 0xf3f938 Type std::pair&lt;std::vector&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt; &gt;,std::list&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt; &gt; &gt;<br />   +0x000 first            : <span style="background-color: rgb(255, 255, 0);">std::vector&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt; &gt;</span><br />   +0x010 second           : <span style="background-color: rgb(255, 255, 0);">std::list&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt; &gt;</span></pre>
</div>

<p>In this case my first value is of type std::vector&lt;std::basic_string&gt;, and my second value is of type std::list&lt;std::basic_string&gt;.</p>

<p>From here, I can move forward in two ways:</p>

<p>1. Use the C++ expression evaluator for both first and second:</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: rgb(244, 244, 244);">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">0:000&gt; <span style="background-color: rgb(255, 255, 0);">?? mypair.first</span><br />class std::vector&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt; &gt;<br />   +0x000 _Myproxy         : 0x01586760 std::_Container_proxy<br />   +0x004 _Myfirst         : 0x01586aa8 std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />   +0x008 _Mylast          : 0x01586afc std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />   +0x00c _Myend           : 0x01586afc std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br /><br />0:000&gt; <span style="background-color: rgb(255, 255, 0);">?? mypair.second</span><br />class std::list&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt; &gt;<br />   +0x000 _Myproxy         : 0x01586c70 std::_Container_proxy<br />   +0x004 _Myhead          : 0x01586c10 std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt;<br />   +0x008 _Mysize          : 3</pre>
</div>

<p>2. Use the offsets to get the addresses and use dt to display the type instances:</p>

<p>From the output of dt mypair above,&#160; the pair is at 0xf3f938. The first value is at offset 0x000, and the second value is at offset 0x010. With this info, I can ask the debugger to display the specific types at the specific addresses</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: rgb(244, 244, 244);">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">0:000&gt; dt mypair<br />Local var @ <span style="background-color: rgb(255, 255, 0);">0xfbf730</span> Type std::pair&lt;std::vector&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt; &gt;,std::list&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt; &gt; &gt;<br />   <span style="background-color: rgb(255, 255, 0);">+0x000</span> first            : <span style="background-color: rgb(255, 255, 0);">std::vector&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt; &gt;</span><br />   <span style="background-color: rgb(255, 255, 0);">+0x010</span> second           : <span style="background-color: rgb(255, 255, 0);">std::list&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt; &gt;</span><br /><br />0:000&gt; <span style="background-color: rgb(255, 255, 0);">dt 0xfbf730 std::vector&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt; &gt;<br />pair!std::vector&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt; &gt;</span><br />   +0x000 _Myproxy         : 0x01586760 std::_Container_proxy<br />   +0x004 _Myfirst         : 0x01586aa8 std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />   +0x008 _Mylast          : 0x01586afc std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />   +0x00c _Myend           : 0x01586afc std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br /><br />0:000&gt; <span style="background-color: rgb(255, 255, 0);">dt 0xfbf730+0x10 std::list&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt; &gt;<br />pair!std::list&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt; &gt;</span><br />   +0x000 _Myproxy         : 0x01586c70 std::_Container_proxy<br />   +0x004 _Myhead          : 0x01586c10 std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt;<br />   +0x008 _Mysize          : 3</pre>
</div>

<p>From here I can conveniently reference <a href="http://blogs.msdn.com/b/ambrosew/archive/2013/01/15/debugging-stl-containers-with-windbg-part-1-vector.aspx">part 1</a> and <a href="http://blogs.msdn.com/b/ambrosew/archive/2013/01/15/debugging-stl-containers-with-windbg-part-2-list.aspx">part 2</a> of this series to traverse the containers.</p>]]></content:encoded>
    </item>
    <item>
      <title>Debugging STL Containers with WinDbg: Prolog 2</title>
      <link>https://docs.microsoft.com/archive/blogs/ambrosew/debugging-stl-containers-with-windbg-prolog-2</link>
      <pubDate>Fri, 18 Jan 2013 01:13:00 GMT</pubDate>
      <dc:creator><![CDATA[ambrosew]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ambrosew/2013/01/18/debugging-stl-containers-with-windbg-prolog-2/</guid>
      <description><![CDATA[In the original prolog of the Debugging STL Containers with WinDbg series, I started off with a...]]></description>
      <content:encoded><![CDATA[<p>In the original <a href="http://blogs.msdn.com/b/ambrosew/archive/2013/01/14/debugging-stl-containers-with-windbg-prolog.aspx">prolog</a> of the Debugging STL Containers with WinDbg series, I started off with a simple main.cpp source, compiled it with the Visual Studio compiler, and debugged the executable with WinDbg.</p>
<p>A few folks mentioned that there ought to be some info that covers the steps from having an executable to seeing the debugger output. I had the assumption that if readers were interested in those blog posts they&rsquo;d probably have some experiences with WinDbg. But I do agree that no matter how trivial some things might be, documenting the exact steps could be helpful one way or the other.</p>
<p>So here are my steps.</p>
<p>1. Prepare the Operating System, Compiler, and WinDbg:</p>
<p>a. Install <a href="http://msdn.microsoft.com/en-us/evalcenter/jj554510.aspx">Windows 8 Version 6.2 Build 9200</a>.</p>
<p>b. Install <a href="http://www.microsoft.com/en-us/download/details.aspx?id=30678">Visual Studio Ultimate 2012 Version 11.0.50727.1 RTMREL</a>.</p>
<p>c. Install <a href="http://msdn.microsoft.com/en-us/windows/desktop/hh852363">Windows Software Development Kit (SDK) for Windows 8</a>.</p>
<p>2. Open a Visual Studio command prompt.</p>
<p>In <a href="http://windows.microsoft.com/en-us/windows-8/mouse-keyboard-whats-new">Windows 8</a>, press Windows logo key <img title="Windows logo key" src="http://res2.windows.microsoft.com/resbox/en/6.2/Main/aa922834-ed43-40f1-8830-d5507badb56c_91.jpg" alt="Windows logo key" width="16" height="16" />+Q, and type "Developer Command Prompt for VS2012". Select the resulting app.</p>
<p>Here&rsquo;s what my command prompt looks like where I create main.cpp:</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">C:\Program Files (x86)\Microsoft Visual Studio 11.0&gt;cd\<br />C:\&gt;md Projects<br />C:\&gt;cd Projects<br />C:\Projects&gt;md STL<br />C:\Projects&gt;cd STL<br />C:\Projects\STL&gt;notepad main.cpp<br />C:\Projects\STL&gt;</pre>
</div>
<p>3. Write some code in main.cpp. Here&rsquo;s an example:</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">#include &lt;iostream&gt;<br />#include &lt;string&gt;<br />#include &lt;vector&gt;<br /><br />using namespace std;<br /><br />int main() {<br />    vector&lt;string&gt; ss;<br />    ss.push_back("1");<br />    ss.push_back("2");<br />    ss.push_back("3");<br />    for (int i = 0; i &lt; (int)ss.size(); i++)<br />        cout &lt;&lt; ss[i] &lt;&lt; endl;<br />}</pre>
</div>
<p>4. Save the file, and run the following command to compile it:</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">C:\Projects\STL&gt;cl /EHsc /nologo /W4 /MTd /Zi main.cpp</pre>
</div>
<p>5. Start WinDbg. In <a href="http://windows.microsoft.com/en-us/windows-8/mouse-keyboard-whats-new">Windows 8</a>, press Windows logo key <img title="Windows logo key" src="http://res2.windows.microsoft.com/resbox/en/6.2/Main/aa922834-ed43-40f1-8830-d5507badb56c_91.jpg" alt="Windows logo key" width="16" height="16" />+Q, and type "windbg". Select "WinDbg (X86)".</p>
<p>6. In WinDbg, press <strong>Ctrl+E </strong>(or go to <strong>File</strong>..<strong>Open Executable</strong>), type in <strong>C:\Projects\STL\main.exe</strong> for <strong>File name</strong>, and then click the <strong>Open </strong>button. If you receive a Workspace prompt, click <strong>Yes </strong>to save information for workspace.</p>
<p>7. Type in the following commands, one after another, in WinDbg:</p>
<p>!sym noisy <br />!symfix c:\symbols <br />.reload /f ntdll.dll <br />.reload /f kernel32.dll <br />bp main!main <br />g</p>
<p>At this point here&rsquo;s what your WinDbg Command window might look like (I&rsquo;ve highlighted the commands you need to type in):</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;"><br />Microsoft (R) Windows Debugger Version 6.2.9200.16384 X86<br />Copyright (c) Microsoft Corporation. All rights reserved.<br /><br />CommandLine: C:\Projects\STL\main.exe<br />Symbol search path is: *** Invalid ***<br />****************************************************************************<br />* Symbol loading may be unreliable without a symbol search path.           *<br />* Use .symfix to have the debugger choose a symbol path.                   *<br />* After setting your symbol path, use .reload to refresh symbol locations. *<br />****************************************************************************<br />Executable search path is: <br />ModLoad: 00a90000 00b81000   main.exe<br />ModLoad: 772e0000 77437000   ntdll.dll<br />ModLoad: 770f0000 77220000   C:\Windows\SysWOW64\KERNEL32.DLL<br />ModLoad: 76830000 768d6000   C:\Windows\SysWOW64\KERNELBASE.dll<br />(fac.d10): Break instruction exception - code 80000003 (first chance)<br />*** ERROR: Symbol file could not be found.  Defaulted to export symbols for ntdll.dll - <br />eax=00000000 ebx=00000003 ecx=a0e10000 edx=00000000 esi=00000000 edi=00a900e8<br />eip=7738054d esp=0059f4e4 ebp=0059f510 iopl=0         nv up ei pl zr na pe nc<br />cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246<br />ntdll!LdrResolveDelayLoadsFromDll+0xa86:<br />7738054d cc              int     3<br />0:000&gt; <span style="background-color: #ffff00;">!sym noisy</span><br />noisy mode - symbol prompts on<br />0:000&gt; <span style="background-color: #ffff00;">!symfix c:\symbols</span><br />DBGHELP: Symbol Search Path: <br />DBGHELP: Symbol Search Path: SRV*c:\symbols*http://msdl.microsoft.com/download/symbols<br />DBGHELP: Symbol Search Path: SRV*c:\symbols*http://msdl.microsoft.com/download/symbols<br />0:000&gt; <span style="background-color: #ffff00;">.reload /f ntdll.dll</span><br />DBGHELP: ntdll - public symbols  <br />        c:\symbols\wntdll.pdb\2806B41638B04D8989F13322DD34573A2\wntdll.pdb<br />0:000&gt; <span style="background-color: #ffff00;">.reload /f kernel32.dll</span><br />DBGHELP: KERNEL32 - public symbols  <br />        c:\symbols\wkernel32.pdb\CFACA818EC334A5EAD707CD86C847B4A1\wkernel32.pdb<br />0:000&gt; <span style="background-color: #ffff00;">bp main!main</span><br />SYMSRV:  c:\symbols\main.pdb\2AA57E80024F4D219D902A73C78FEA2D2\main.pdb not found<br />SYMSRV:  http://msdl.microsoft.com/download/symbols/main.pdb/2AA57E80024F4D219D902A73C78FEA2D2/main.pdb not found<br />*** WARNING: Unable to verify checksum for main.exe<br />DBGHELP: main - private symbols &amp; lines <br />        C:\Projects\STL\main.pdb<br />0:000&gt; <span style="background-color: #ffff00;">g</span><br />Breakpoint 0 hit<br />eax=00d42d98 ebx=7efeb000 ecx=00000001 edx=00d45700 esi=00000000 edi=00000000<br />eip=00a91820 esp=0059f958 ebp=0059f9a0 iopl=0         nv up ei pl zr na pe nc<br />cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246<br />main!main:<br />00a91820 55              push    ebp</pre>
</div>
<p>Here&rsquo;s a sample picture of it:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/32/94/metablogapi/3515.WinDbg_683CB4D3.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-32-94-metablogapi/3515.WinDbg_5F00_683CB4D3.png"><img style="border: 0px currentcolor; display: inline; background-image: none;" title="WinDbg" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/32/94/metablogapi/7875.WinDbg_thumb_31CB412A.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-32-94-metablogapi/7875.WinDbg_5F00_thumb_5F00_31CB412A.png" alt="WinDbg" width="548" height="343" border="0" /></a></p>
<p>Here&rsquo;s what happened:</p>
<p><strong>!sym noisy </strong>- Activates noisy symbol loading so that when the debugger loads symbols you get more details like exactly where the symbol was loaded.</p>
<p><strong>!symfix c:\symbols </strong>(or .symfix) - Sets the symbol path to point to Microsoft symbol store. I specified c:\symbols to store downloaded symbols there.</p>
<p><strong>.reload /f ntdll.dll </strong>and <strong>.reload /f kernel32.dll </strong>- Since when this debug session starts I didn&rsquo;t have proper symbol path set, symbols for these two modules were not loaded. After I set the symbol path with !symfix, I&rsquo;m manually reloading the symbols for these two modules. This is not necessary in this specific case but in general it&rsquo;s a good practice to have symbols for these two modules.</p>
<p><strong>bp main!main</strong> - Sets a breakpoint at main().</p>
<p><strong>g</strong> - Go (F5), just like what you&rsquo;re accustomed to&nbsp;in Visual Studio.</p>
<p>8. At this point you can just press <strong>F10</strong> or the <strong>Step Over </strong>button on the toolbar to step over the source code until you hit the <strong>for </strong>line. This is where the code added three elements into the vector.</p>
<p>9. Now in the debugger&rsquo;s Command window you can type commands like dt ss to look at the vector:</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">0:000&gt; dt ss<br />Local var @ 0x59f8dc Type std::vector&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt; &gt;<br />   +0x000 _Myproxy         : 0x00b750f8 std::_Container_proxy<br />   +0x004 _Myfirst         : 0x0059f8ec std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />   +0x008 _Mylast          : 0x00ae3b1a std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />   +0x00c _Myend           : 0x00000008 std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;</pre>
</div>
<p>There you go. The steps that accompany the rest of the series.</p>
<p>You know what, actually I&rsquo;m glad I wrote these down. I might need to reference these sometime later myself.</p>
<hr />
<p>P.S. I was tempted to go back to the prolog and add a section with an "Update" label. Sounded logical, but I didn&rsquo;t want to bloat that blog post into a book. Hence this post, Prolog 2. I&rsquo;ve tagged this post with the same tags as the other posts in the series, so at least the tag cloud works as it&rsquo;s supposed to. There are so many other questions that could spawn from this little post, like "why not use Visual Studio to create main.cpp", "why X86 and not X64", "why c:\symbols and not d:\symbols", or even "why Windows 8 and not Windows XP or Windows 7". I&rsquo;ll re-evaluate the need to expand on these points at a later time :)</p>
<p>P.P.S. Just a gentle reminder, if you&rsquo;re still using Windows XP. Its support ends on <a href="http://www.microsoft.com/en-us/windows/endofsupport.aspx">April 8, 2014</a>!</p>]]></content:encoded>
    </item>
    <item>
      <title>Debugging STL Containers with WinDbg Part 3: Map</title>
      <link>https://docs.microsoft.com/archive/blogs/ambrosew/debugging-stl-containers-with-windbg-part-3-map</link>
      <pubDate>Tue, 15 Jan 2013 02:08:00 GMT</pubDate>
      <dc:creator><![CDATA[ambrosew]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ambrosew/2013/01/15/debugging-stl-containers-with-windbg-part-3-map/</guid>
      <description><![CDATA[For previous posts of this series, check out the following links:  Debugging STL Containers with...]]></description>
      <content:encoded><![CDATA[<p>For previous posts of this series, check out the following links:</p>  <p><a href="http://blogs.msdn.com/b/ambrosew/archive/2013/01/14/debugging-stl-containers-with-windbg-prolog.aspx">Debugging STL Containers with WinDbg: Prolog</a>     <br /><a href="http://blogs.msdn.com/b/ambrosew/archive/2013/01/15/debugging-stl-containers-with-windbg-part-1-vector.aspx">Debugging STL Containers with WinDbg Part 1: Vector</a>     <br /><a href="http://blogs.msdn.com/b/ambrosew/archive/2013/01/15/debugging-stl-containers-with-windbg-part-2-list.aspx">Debugging STL Containers with WinDbg Part 2: List</a></p>  <p>Let’s now look at <a href="http://www.bing.com/search?q=stl+map+site%3Amsdn.microsoft.com">maps</a>. Like lists, a map container manages a varying-length sequence of elements but as a (nearly) balanced ordered tree of nodes, each storing one element. An element consists of a key, for ordering sequence, and a mapped value. Underneath it’s an implementation of an ordered <a href="http://www.bing.com/search?q=red-black+tree+site%3Awikipedia.org">red-black tree</a> (a special type of binary tree) of {key, mapped} values. The source in Visual Studio 2012 can be found in C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\crt\src\map.</p>  <hr />  <p>Before we delve into a map in WinDbg, it’s probably a good idea to understand the basic structure of a red-black tree so to make sense out of the output when you debug.</p>  <p>A red-black tree is a special kind of binary tree. In a red-black tree, a node is either red or black. These two &quot;colors&quot; are essentially used for balancing the tree over time when you insert and remove nodes. For tree traversal in this case, the &quot;color&quot; of a node is irrelevant so feel free to set it aside for now.</p>  <p>Each tree node has the following members that are of interest for our purpose:</p>  <p>_Left - Points to left subtree, or smallest element if head.    <br />_Parent – Points to the node’s parent, or root of the tree if head.     <br />_Right - Points to right subtree, or largest element if head.     <br />_Myval - the stored key/value pair.</p>  <p>Just like binary trees, each node can have a left subtree and a right subtree. Left and right branches so to speak.</p>  <p>Each node stores the key and value of a node. Keys are not limited to numerical. You can have a comparison function or less-than operator defined for the key type you desire. When you dereference an iterator, you get back a pair - first corresponds to the key, and second to the value.</p>  <p>I hope it’ll make sense when you look into an instance of a map and draw a logical picture of it.</p>  <hr />  <p>Take the following example:</p>  <div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: rgb(244, 244, 244);">   <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">C:\Projects\STL&gt;type main.cpp<br />#include &lt;iostream&gt;<br />#include &lt;string&gt;<br />#include &lt;map&gt;<br /><br />using namespace std;<br /><br />int main() {<br />    map&lt;int, string&gt; mymap;<br />    mymap[1] = &quot;Map1&quot;;<br />    mymap[2] = &quot;Map2&quot;;<br />    mymap[3] = &quot;Map3&quot;;<br />    mymap[4] = &quot;Map4&quot;;<br />    mymap[5] = &quot;Map5&quot;;<br />    for (map&lt;int,string&gt;::iterator mi = mymap.begin(); mi != mymap.end(); ++mi)<br />        cout &lt;&lt; (*mi).first &lt;&lt; &quot;: &quot; &lt;&lt; (*mi).second &lt;&lt; endl;<br />}<br />C:\Projects\STL&gt;cl /EHsc /nologo /W4 /MTd /Zi main.cpp<br />main.cpp<br /><br />C:\Projects\STL&gt;main<br />1: Map1<br />2: Map2<br />3: Map3<br />4: Map4<br />5: Map5</pre>
</div>

<p>In this example we have 5 nodes so it’s simple enough to traverse, yet it has enough nodes to let us see a tree structure that’s easy to understand.</p>

<p>Let’s start by looking at the map instance:</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: rgb(244, 244, 244);">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">0:000&gt; dt mymap<br />Local var @ 0xd2fb70 Type std::map&lt;int,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::less&lt;int&gt;,std::allocator&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt; &gt; &gt;<br />   +0x000 _Myproxy         : 0x00f56440 std::_Container_proxy<br />   +0x004 _Myhead          : 0x00f55428 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x008 _Mysize          : 5</pre>
</div>

<p>_Mysize is obvious, the number of nodes in the tree. _Myhead is a little trickier. _Myhead does not point to the root. _Myhead-&gt;_Parent does. Keep this in mind.</p>

<p>To start off the journey, let’s dump out the head node (it helps if you keep your eyes on the _Left/_Right/_Parent values):</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; max-height: 200px; background-color: rgb(244, 244, 244);">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">0:000&gt; dt 0x00f55428 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />main!std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x000 _Left            : 0x00f56778 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x004 _Parent          : 0x00f56830 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x008 _Right           : 0x00f56a58 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x00c _Color           : 1 <span style="color: rgb(0, 96, 128);">''</span><br />   +0x00d _Isnil           : 1 <span style="color: rgb(0, 96, 128);">''</span><br />   +0x010 _Myval           : std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;</pre>
</div>

<p>As stated earlier, head node’s _Left points to the smallest element, and its _Right points to the largest element. _Left and _Right at this point are not really necessary for us to start the traversal, so ignore them for now. After we traversed the tree you can come back and double-check the values.</p>

<p>Head node’s _Parent points to the root of the tree, so let’s start there. Notice that you can specify which member of the type to display, so here we specified _Left, _Parent, _Right, and _Myval. For _Myval we want to drill down to the pair’s first and second values, and also one more level deeper into _Bx as well to see the string buffer, hence we used _Myval… (with three dots).</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: rgb(244, 244, 244);">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">0:000&gt; dt 0x00f56830 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt; _Left _Parent _Right _Myval...<br />main!std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x000 _Left     : 0x00f56778 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x004 _Parent   : 0x00f55428 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x008 _Right    : 0x00f569a0 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x010 _Myval    : <br />      +0x000 first     : 0n2<br />      +0x004 second    : <br />         +0x000 _Myproxy  : <br />         +0x004 _Bx       : <br />            +0x000 _Buf      : [16]  &quot;Map2&quot;<br />            +0x000 _Ptr      : 0x3270614d  &quot;--- memory read error at address 0x3270614d ---&quot;<br />            +0x000 _Alias    : [16]  &quot;Map2&quot;<br />         +0x014 _Mysize   : 4<br />         +0x018 _Myres    : 0xf<br />         =003d7440 npos      : 0xffffffff</pre>
</div>

<p>So the root node contains the &lt;2,&quot;Map2&quot;&gt; pair. From here you can dt _Left and _Right for each node. If you encounter a _Left or _Right value that is the same as the head node, that means there’s no more subtree there, and you’re done with that branch.</p>

<p>Here’s the complete output. I’ve added some debugger comments for you to follow.</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: rgb(244, 244, 244);">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">0:000&gt; dt 0x00f56830 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt; _Left _Parent _Right _Myval...<br />main!std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x000 _Left     : 0x00f56778 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x004 _Parent   : 0x00f55428 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x008 _Right    : 0x00f569a0 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x010 _Myval    : <br />      +0x000 first     : 0n2<br />      +0x004 second    : <br />         +0x000 _Myproxy  : <br />         +0x004 _Bx       : <br />            +0x000 _Buf      : [16]  &quot;Map2&quot;<br />            +0x000 _Ptr      : 0x3270614d  &quot;--- memory read error at address 0x3270614d ---&quot;<br />            +0x000 _Alias    : [16]  &quot;Map2&quot;<br />         +0x014 _Mysize   : 4<br />         +0x018 _Myres    : 0xf<br />         =003d7440 npos      : 0xffffffff<br /><br />0:000&gt; * _Parent points to _Myhead, which is expected.<br />0:000&gt; * Both _Left and _Right point to somewhere other than _Myhead,<br />0:000&gt; * so they both have branches.<br /><br />0:000&gt; * Dump the left subtree.<br /><br />0:000&gt; dt 0x00f56778 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt; _Left, _Parent, _Right, _Myval...<br />main!std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x000 _Left     : 0x00f55428 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x004 _Parent   : 0x00f56830 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x008 _Right    : 0x00f55428 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x010 _Myval    : <br />      +0x000 first     : 0n1<br />      +0x004 second    : <br />         +0x000 _Myproxy  : <br />         +0x004 _Bx       : <br />            +0x000 _Buf      : [16]  &quot;Map1&quot;<br />            +0x000 _Ptr      : 0x3170614d  &quot;--- memory read error at address 0x3170614d ---&quot;<br />            +0x000 _Alias    : [16]  &quot;Map1&quot;<br />         +0x014 _Mysize   : 4<br />         +0x018 _Myres    : 0xf<br />         =003d7440 npos      : 0xffffffff<br /><br />0:000&gt; * Here both _Left and _Right point to _Myhead, so we're done with this branch.<br /><br />0:000&gt; * Now dump the right subtree.<br /><br />0:000&gt; dt 0x00f569a0 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt; _Left, _Parent, _Right, _Myval...<br />main!std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x000 _Left     : 0x00f568e8 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x004 _Parent   : 0x00f56830 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x008 _Right    : 0x00f56a58 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x010 _Myval    : <br />      +0x000 first     : 0n4<br />      +0x004 second    : <br />         +0x000 _Myproxy  : <br />         +0x004 _Bx       : <br />            +0x000 _Buf      : [16]  &quot;Map4&quot;<br />            +0x000 _Ptr      : 0x3470614d  &quot;--- memory read error at address 0x3470614d ---&quot;<br />            +0x000 _Alias    : [16]  &quot;Map4&quot;<br />         +0x014 _Mysize   : 4<br />         +0x018 _Myres    : 0xf<br />         =003d7440 npos      : 0xffffffff<br /><br />0:000&gt; * Both _Left and _Right point to somewhere other than _Myhead,<br />0:000&gt; * so they both have branches.<br /><br />0:000&gt; * Dump the left subtree.<br /><br />0:000&gt; dt 0x00f568e8 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt; _Left, _Parent, _Right, _Myval...<br />main!std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x000 _Left     : 0x00f55428 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x004 _Parent   : 0x00f569a0 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x008 _Right    : 0x00f55428 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x010 _Myval    : <br />      +0x000 first     : 0n3<br />      +0x004 second    : <br />         +0x000 _Myproxy  : <br />         +0x004 _Bx       : <br />            +0x000 _Buf      : [16]  &quot;Map3&quot;<br />            +0x000 _Ptr      : 0x3370614d  &quot;--- memory read error at address 0x3370614d ---&quot;<br />            +0x000 _Alias    : [16]  &quot;Map3&quot;<br />         +0x014 _Mysize   : 4<br />         +0x018 _Myres    : 0xf<br />         =003d7440 npos      : 0xffffffff<br /><br />0:000&gt; * Both _Left and _Right point to _Myhead, so we're done with this branch.<br /><br />0:000&gt; * Now dump the right subtree.<br /><br />0:000&gt; dt 0x00f56a58 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt; _Left, _Parent, _Right, _Myval...<br />main!std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x000 _Left     : 0x00f55428 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x004 _Parent   : 0x00f569a0 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x008 _Right    : 0x00f55428 std::_Tree_node&lt;std::pair&lt;int const ,std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;,void *&gt;<br />   +0x010 _Myval    : <br />      +0x000 first     : 0n5<br />      +0x004 second    : <br />         +0x000 _Myproxy  : <br />         +0x004 _Bx       : <br />            +0x000 _Buf      : [16]  &quot;Map5&quot;<br />            +0x000 _Ptr      : 0x3570614d  &quot;--- memory read error at address 0x3570614d ---&quot;<br />            +0x000 _Alias    : [16]  &quot;Map5&quot;<br />         +0x014 _Mysize   : 4<br />         +0x018 _Myres    : 0xf<br />         =003d7440 npos      : 0xffffffff<br /><br />0:000&gt; * Again both _Left and _Right point to _Myhead, so we're done with this branch as well.<br />0:000&gt; * All branches traversed. We're done.</pre>
</div>

<p>The diagram below provides a logical picture of the tree: </p>

<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/32/94/metablogapi/6886.Drawing1_017A9E1A.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-32-94-metablogapi/6886.Drawing1_5F00_017A9E1A.png"><img title="Drawing1" style="border: 0px currentcolor; display: inline; background-image: none;" border="0" alt="Drawing1" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/32/94/metablogapi/3247.Drawing1_thumb_18C5A28B.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-32-94-metablogapi/3247.Drawing1_5F00_thumb_5F00_18C5A28B.png" width="542" height="406" /></a></p>

<p>Unlike vectors, I don’t have a script to dump the nodes for map containers. Maybe I’ll find some time later to address this shortcoming. Until then, I hope the information presented so far is helpful to you.</p>]]></content:encoded>
    </item>
    <item>
      <title>Debugging STL Containers with WinDbg Part 2: List</title>
      <link>https://docs.microsoft.com/archive/blogs/ambrosew/debugging-stl-containers-with-windbg-part-2-list</link>
      <pubDate>Mon, 14 Jan 2013 22:41:00 GMT</pubDate>
      <dc:creator><![CDATA[ambrosew]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ambrosew/2013/01/14/debugging-stl-containers-with-windbg-part-2-list/</guid>
      <description><![CDATA[For previous posts of this series, check out the following links:
Debugging STL Containers with...]]></description>
      <content:encoded><![CDATA[<p>For previous posts of this series, check out the following links:</p>
<p><a href="http://blogs.msdn.com/b/ambrosew/archive/2013/01/14/debugging-stl-containers-with-windbg-prolog.aspx">Debugging STL Containers with WinDbg: Prolog</a> <br /><a href="http://blogs.msdn.com/b/ambrosew/archive/2013/01/15/debugging-stl-containers-with-windbg-part-1-vector.aspx">Debugging STL Containers with WinDbg Part 1: Vector</a></p>
<p>Let&rsquo;s now look at <a href="http://www.bing.com/search?q=stl+list+site%3Amsdn.microsoft.com" target="_blank">lists</a>. A list container manages a varying-length sequence of elements as a bidirectional linked list of nodes, each storing one element. The source in Visual Studio 2012 can be found in C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\crt\src\list.</p>
<p>Take the following example:</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">C:\Projects\STL&gt;type main.cpp<br />#include &lt;iostream&gt;<br />#include &lt;string&gt;<br />#include &lt;list&gt;<br /><br />using namespace std;<br /><br />int main() {<br />    list&lt;string&gt; mylist;<br />    mylist.insert(mylist.end(), "one");<br />    mylist.insert(mylist.end(), "two");<br />    mylist.insert(mylist.end(), "three");<br />    for (list&lt;string&gt;::iterator li = mylist.begin(); li != mylist.end(); ++li)<br />        cout &lt;&lt; (*li) &lt;&lt; endl;<br />}<br />C:\Projects\STL&gt;cl /EHsc /nologo /W4 /MTd /Zi main.cpp<br />main.cpp<br /><br />C:\Projects\STL&gt;main<br />one<br />two<br />three</pre>
</div>
<p>The first step is to get the pointer to the head node of the linked list. _Myhead gives you this information. _Mysize gives you the number of elements in the list.</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">0:000&gt; dt mylist<br />Local var @ 0xebf7c8 Type std::list&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt; &gt;<br />   +0x000 _Myproxy         : 0x010e6440 std::_Container_proxy<br />   +0x004 _Myhead          : <span style="background-color: #ffff00;">0x010e5428 std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt;</span><br />   +0x008 _Mysize          : 3<br />
0:000&gt; dt 0x010e5428 std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt;<br />main!std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt;<br />   +0x000 _Next            : <span style="background-color: #ffff00;">0x010e64d0 std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt;</span><br />   +0x004 _Prev            : 0x010e6868 std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt;<br />   +0x008 _Myval           : std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;</pre>
</div>
<p>Note that _Myhead points to the head node. _Myhead-&gt;_Next points to the first node, and _Myhead-&gt;_Prev points to the last node. The last node&rsquo;s _Next simply points back to _Myhead.</p>
<p>To go through each node in the linked list, simply grab the first node and dt on _Next, and repeat for each node in the list, until _Next points to _Myhead:</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">0:000&gt; dt 0x010e5428 std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt;<br />main!std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt;<br />   +0x000 _Next            : 0x010e64d0 std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt;<br />   +0x004 _Prev            : 0x010e6868 std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt;<br />   +0x008 _Myval           : std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br /><br />0:000&gt; dt 0x010e64d0 std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt;<br />main!std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt;<br />   +0x000 _Next            : 0x010e67c0 std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt;<br />   +0x004 _Prev            : 0x010e5428 std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt;<br />   +0x008 _Myval           : std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br /><br />0:000&gt; dt 0x010e67c0 std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt;<br />main!std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt;<br />   +0x000 _Next            : 0x010e6868 std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt;<br />   +0x004 _Prev            : 0x010e64d0 std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt;<br />   +0x008 _Myval           : std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br /><br />0:000&gt; dt 0x010e6868 std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt;<br />main!std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt;<br />   +0x000 _Next            : 0x010e5428 std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt;<br />   +0x004 _Prev            : 0x010e67c0 std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt;<br />   +0x008 _Myval           : std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;</pre>
</div>
<p>To look at each node&rsquo;s value (_Myval), simply tell dt to display the _Myval field. Note the two dots (..) which means "expand the field two levels deep". In this case, we want to see inside _Myval (first level), then we want to see inside _Bx (second level).</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">0:000&gt; dt 0x010e64d0 std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt; <span style="background-color: #ffff00;">_Myval..</span><br />main!std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt;<br />   +0x008 _Myval   : <br />      +0x000 _Myproxy : <br />      +0x004 _Bx      : <br />         +0x000 _Buf     : [16]  "one"<br />         +0x000 _Ptr     : 0x00656e6f  "--- memory read error at address 0x00656e6f ---"<br />         +0x000 _Alias   : [16]  "one"<br />      +0x014 _Mysize  : 3<br />      +0x018 _Myres   : 0xf<br />      =00994878 npos     : 0xffffffff</pre>
</div>
<p>The dt command does support -l option which can help you traverse the linked list using _Next, like so:</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">0:000&gt; dt 0x010e64d0 std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt; <span style="background-color: #ffff00;">-l _Next</span> _Myval..<br />main!std::_List_node&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,void *&gt;<br />_Next at 0x010e64d0<br />---------------------------------------------<br />   +0x008 _Myval   : <br />      +0x000 _Myproxy : <br />      +0x004 _Bx      : <br />         +0x000 _Buf     : [16]  "one"<br />         +0x000 _Ptr     : 0x00656e6f  "--- memory read error at address 0x00656e6f ---"<br />         +0x000 _Alias   : [16]  "one"<br />      +0x014 _Mysize  : 3<br />      +0x018 _Myres   : 0xf<br />      =00994878 npos     : 0xffffffff<br /><br />_Next at 0x010e67c0<br />---------------------------------------------<br />   +0x008 _Myval   : <br />      +0x000 _Myproxy : <br />      +0x004 _Bx      : <br />         +0x000 _Buf     : [16]  "two"<br />         +0x000 _Ptr     : 0x006f7774  "--- memory read error at address 0x006f7774 ---"<br />         +0x000 _Alias   : [16]  "two"<br />      +0x014 _Mysize  : 3<br />      +0x018 _Myres   : 0xf<br />      =00994878 npos     : 0xffffffff<br /><br />_Next at 0x010e6868<br />---------------------------------------------<br />   +0x008 _Myval   : <br />      +0x000 _Myproxy : <br />      +0x004 _Bx      : <br />         +0x000 _Buf     : [16]  "three"<br />         +0x000 _Ptr     : 0x65726874  "--- memory read error at address 0x65726874 ---"<br />         +0x000 _Alias   : [16]  "three"<br />      +0x014 _Mysize  : 5<br />      +0x018 _Myres   : 0xf<br />      =00994878 npos     : 0xffffffff<br /><br />_Next at 0x010e5428<br />---------------------------------------------<br />   +0x008 _Myval   : <br />      +0x000 _Myproxy : <br />      +0x004 _Bx      : <br />         +0x000 _Buf     : [16]  "???"<br />         +0x000 _Ptr     : 0xcdcdcdcd  "--- memory read error at address 0xcdcdcdcd ---"<br />         +0x000 _Alias   : [16]  "???"<br />      +0x014 _Mysize  : 0xcdcdcdcd<br />      +0x018 _Myres   : 0xcdcdcdcd<br />      =00994878 npos     : 0xffffffff</pre>
</div>
<p>Simple as mud. Remember to check out !list extension as well, which allows you to execute debugger commands repeatedly, once for every element in the linked list. For those lists with complex values, it might comes handy.</p>
<p>This is as much as I want to cover for now. Have a great day~!</p>
<hr />
<p>P.S. Now that I&rsquo;m at Part 2 in the series, I realized I used "Prolog" in the title of the beginning post instead of "Introduction&rdquo; or "Preface" or something. Does it mean I need to have an Epilog? For blog posts I guess having an Epilog means there&rsquo;s a hard end to the series. Or should I go back and change the title from Prolog to something else? I guess except my freshman year&rsquo;s English teacher, nobody really cares :) Moving on..</p>
<p>P.P.S. That particular English teacher was the very first person I know who pronounced, in disgust, that ALL computer science student&rsquo;s grammar sucks. There might be some truth to it, and I still try my best to write properly up till now, but I did picked assembly (Computer Science) over English (literature). Woot~!</p>]]></content:encoded>
    </item>
    <item>
      <title>Debugging STL Containers with WinDbg Part 1: Vector</title>
      <link>https://docs.microsoft.com/archive/blogs/ambrosew/debugging-stl-containers-with-windbg-part-1-vector</link>
      <pubDate>Mon, 14 Jan 2013 20:06:33 GMT</pubDate>
      <dc:creator><![CDATA[ambrosew]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ambrosew/2013/01/14/debugging-stl-containers-with-windbg-part-1-vector/</guid>
      <description><![CDATA[In the prolog of this series, I dabbled a bit on some of the reasons why you’d want to walk the...]]></description>
      <content:encoded><![CDATA[<p>In the <a href="http://blogs.msdn.com/b/ambrosew/archive/2013/01/14/debugging-stl-containers-with-windbg-prolog.aspx" target="_blank">prolog</a> of this series, I dabbled a bit on some of the reasons why you’d want to walk the containers in WinDbg yourself instead of using extensions like !stl.</p>  <p>Just to put a stick on the ground for this series, I’m using Visual Studio Ultimate 2012 Version 11.0.50727.1 RTMREL on Windows 8 Version 6.2 Build 9200, and WinDbg 6.2.9200.16384 from <a href="http://msdn.microsoft.com/en-us/windows/desktop/hh852363">Windows Software Development Kit (SDK) for Windows 8</a>. Although I mentioned in the prolog that the containers’ types do change a little between Visual C++ releases, the concepts in this series should still apply.</p>  <p>First let’s look at <a href="http://www.bing.com/search?q=stl+vector+site%3Amsdn.microsoft.com" target="_blank">vectors</a>. A vector container manages a sequence of elements as a contiguous block of storage, essentially an array that grows on demand. The source in Visual Studio 2012 can be found in C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\crt\src\vector.</p>  <p>Take the following example:</p>  <div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: rgb(244, 244, 244);">   <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">C:\Projects\STL&gt;type main.cpp<br />#include &lt;iostream&gt;<br />#include &lt;string&gt;<br />#include &lt;vector&gt;<br /><br />using namespace std;<br /><br />int main() {<br />    vector&lt;string&gt; ss;<br />    ss.push_back(&quot;1&quot;);<br />    ss.push_back(&quot;2&quot;);<br />    ss.push_back(&quot;3&quot;);<br />    for (int i = 0; i &lt; (int)ss.size(); i++)<br />        cout &lt;&lt; ss[i] &lt;&lt; endl;<br />}<br />C:\Projects\STL&gt;cl /EHsc /nologo /W4 /MTd /Zi main.cpp<br />main.cpp<br /><br />C:\Projects\STL&gt;main<br />1<br />2<br />3</pre>
</div>

<p>The first step is to look at the size of each element, be it string or other types. In this case it’s a string vector:</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: rgb(244, 244, 244);">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">0:000&gt; dt ss<br />Local var @ 0xd4f938 Type <span style="background-color: rgb(255, 255, 0);">std::vector&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;</span>,std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt; &gt;<br />   +0x000 _Myproxy         : 0x00e56418 std::_Container_proxy<br />   +0x004 _Myfirst         : 0x00e56858 std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />   +0x008 _Mylast          : 0x00e568ac std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />   +0x00c _Myend           : 0x00e568ac std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br /></pre>
</div>

<p>_Myfirst - pointer to beginning of array. 
  <br />_Mylast - pointer to current end of sequence. 

  <br />_Myend - pointer to end of array.</p>

<p>To find out the size of each element, use dt again for the element type, with the -v option to get the size:</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: rgb(244, 244, 244);">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">0:000&gt; dt -v main!std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />class std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;, 166 elements, <span style="background-color: rgb(255, 255, 0);">0x1c bytes</span><br />   +0x000 __BaseClass class std::_String_alloc&lt;0,std::_String_base_types&lt;char,std::allocator&lt;char&gt; &gt; &gt;, 15 elements, 0x1c bytes<br />   +0x000 __BaseClass class std::_String_val&lt;std::_Simple_types&lt;char&gt; &gt;, 24 elements, 0x1c bytes<br />   +0x000 __BaseClass struct std::_Container_base12, 9 elements, 0x4 bytes<br />...</pre>
</div>

<p>There’s a whole lot of things that dt spews with -v. Alternatively you can always just use dt and calculate the size yourself:</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: rgb(244, 244, 244);">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">0:000&gt; dt main!std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />   +0x000 _Myproxy         : Ptr32 std::_Container_proxy<br />   +0x004 _Bx              : std::_String_val&lt;std::_Simple_types&lt;char&gt; &gt;::_Bxty<br />   +0x014 _Mysize          : Uint4B<br />   <span style="background-color: rgb(255, 255, 0);">+0x018</span> _Myres           : <span style="background-color: rgb(255, 255, 0);">Uint4B</span><br />   =003d31cc npos             : Uint4B<br /></pre>
</div>

<p>At offset 0x18, the last member is Uint4B in size. So the total size is 0x18+4, or 0x1c bytes. Easy enough.</p>

<p>Let’s look at the first element. The beginning of the array is at _Myfirst, so just copy the output for _Myfirst from dt ss earlier and do a dt –r on it:</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: rgb(244, 244, 244);">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">0:000&gt; dt ss<br />Local var @ 0xd4f938 Type std::vector&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt; &gt;<br />   +0x000 _Myproxy         : 0x00e56418 std::_Container_proxy<br />   +0x004 _Myfirst         : <span style="background-color: rgb(255, 255, 0);">0x00e56858 std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;</span><br />   +0x008 _Mylast          : 0x00e568ac std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />   +0x00c _Myend           : 0x00e568ac std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br /><br />0:000&gt; dt -r <span style="background-color: rgb(255, 255, 0);">0x00e56858 std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;</span><br />main!std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />   +0x000 _Myproxy         : 0x00e564a8 std::_Container_proxy<br />      +0x000 _Mycont          : 0x00e56858 std::_Container_base12<br />         +0x000 _Myproxy         : 0x00e564a8 std::_Container_proxy<br />      +0x004 _Myfirstiter     : (null) <br />   +0x004 _Bx              : std::_String_val&lt;std::_Simple_types&lt;char&gt; &gt;::_Bxty<br />      +0x000 _Buf             : [16]  &quot;1&quot;<br />      +0x000 _Ptr             : 0xcdcd0031  &quot;--- memory read error at address 0xcdcd0031 ---&quot;<br />      +0x000 _Alias           : [16]  &quot;1&quot;<br />   +0x014 _Mysize          : 1<br />   +0x018 _Myres           : 0xf<br />   =003d31cc npos             : 0xffffffff<br /></pre>
</div>

<p>For strings, the most interesting member would be _Bx, which is a union type. From C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\crt\src\xstring:</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: rgb(244, 244, 244);">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">union _Bxty<br />    {    // storage for small buffer or pointer to larger one<br />    value_type _Buf[_BUF_SIZE];<br />    pointer _Ptr;<br />    char _Alias[_BUF_SIZE];    // to permit aliasing<br />    } _Bx;</pre>
</div>

<p>Your string data will either be in _Buf array for short string, or in the heap pointed to by _Ptr. _Mysize is the current length of the string, and _Myres is the current storage reserved for the string. _Alias is there since Visual Studio 2010 for aliasing.</p>

<p>Let’s go back to vectors.</p>

<p>To find the next element from the first, all we need to do is add the element size to the first element’s address. Here’s the second element in the vector:</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: rgb(244, 244, 244);">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">0:000&gt; dt -r 0x00e56858<span style="background-color: rgb(255, 255, 0);">+0x1c</span> std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />main!std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />   +0x000 _Myproxy         : 0x00e568e8 std::_Container_proxy<br />      +0x000 _Mycont          : 0x00e56874 std::_Container_base12<br />         +0x000 _Myproxy         : 0x00e568e8 std::_Container_proxy<br />      +0x004 _Myfirstiter     : (null) <br />   +0x004 _Bx              : std::_String_val&lt;std::_Simple_types&lt;char&gt; &gt;::_Bxty<br />      +0x000 _Buf             : [16]  &quot;2&quot;<br />      +0x000 _Ptr             : 0xcdcd0032  &quot;--- memory read error at address 0xcdcd0032 ---&quot;<br />      +0x000 _Alias           : [16]  &quot;2&quot;<br />   +0x014 _Mysize          : 1<br />   +0x018 _Myres           : 0xf<br />   =003d31cc npos             : 0xffffffff</pre>
</div>

<p>And the third:</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: rgb(244, 244, 244);">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">0:000&gt; dt -r 0x00e56858<span style="background-color: rgb(255, 255, 0);">+0x1c+0x1c</span> std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />main!std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />   +0x000 _Myproxy         : 0x00e56750 std::_Container_proxy<br />      +0x000 _Mycont          : 0x00e56890 std::_Container_base12<br />         +0x000 _Myproxy         : 0x00e56750 std::_Container_proxy<br />      +0x004 _Myfirstiter     : (null) <br />   +0x004 _Bx              : std::_String_val&lt;std::_Simple_types&lt;char&gt; &gt;::_Bxty<br />      +0x000 _Buf             : [16]  &quot;3&quot;<br />      +0x000 _Ptr             : 0xcdcd0033  &quot;--- memory read error at address 0xcdcd0033 ---&quot;<br />      +0x000 _Alias           : [16]  &quot;3&quot;<br />   +0x014 _Mysize          : 1<br />   +0x018 _Myres           : 0xf<br />   =003d31cc npos             : 0xffffffff</pre>
</div>

<p>And so on and so forth.</p>

<p>If you have a large number of elements to examine, you’d probably want the computer to do the enumeration for you. A <a href="http://msdn.microsoft.com/en-us/library/ff560137.aspx" target="_blank">debugger script</a> will fit the bill. Here’s an example:</p>

<p>1. Store the following content in a text file named, say, vectorstring.txt, and put it in, say, c:\temp.</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: rgb(244, 244, 244);">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">$$ Initialize our pseudo-registers<br />r? $t0=${$arg1}._Myfirst<br />r? $t1=${$arg1}._Mylast<br /><br />$$ Go through the elements until _Mylast is reached.<br />.while (@$t0 != @$t1)<br />{<br />  $$ Dump the string content<br />  da @@c++(&amp;@$t0-&gt;_Bx)<br /><br />  $$ Go to the next element.<br />  r? $t0=@$t0+1<br />}</pre>
</div>

<p>2. In the debugger, run the script with argument: $$&gt;a&lt; vectorstring.txt &lt;vector&gt;</p>

<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: rgb(244, 244, 244);">
  <pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: rgb(244, 244, 244);">0:000&gt; $$&gt;a&lt; c:\temp\vectorstring.txt ss<br />00e5685c  &quot;1&quot;<br />00e56878  &quot;2&quot;<br />00e56894  &quot;3&quot;</pre>
</div>

<p>This could be useful either to just look at the data of each element, or walk the vector array for suspicious values (e.g. buffer overruns). Customize the script to your heart’s content.</p>

<p>This is just about all I needed in order to peel the vector container. I hope this is a good start of the series for you. As always, happy debugging!</p>]]></content:encoded>
    </item>
    <item>
      <title>Debugging STL Containers with WinDbg: Prolog</title>
      <link>https://docs.microsoft.com/archive/blogs/ambrosew/debugging-stl-containers-with-windbg-prolog</link>
      <pubDate>Mon, 14 Jan 2013 02:44:00 GMT</pubDate>
      <dc:creator><![CDATA[ambrosew]]></dc:creator>
      <guid
        isPermaLink="false">https://blogs.msdn.microsoft.com/ambrosew/2013/01/14/debugging-stl-containers-with-windbg-prolog/</guid>
      <description><![CDATA[For those who use Standard Template Library in applications and depend on WinDbg to troubleshoot,...]]></description>
      <content:encoded><![CDATA[<p>For those who use Standard Template Library in applications and depend on WinDbg to troubleshoot, debugging STL containers has always been a little back-bending. There are various STL extensions available, but they sometimes just don&rsquo;t play nice (fail, or generate an exception).</p>
<p>Take the following example:</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">C:\Projects\STL&gt;type main.cpp<br />#include &lt;iostream&gt;<br />#include &lt;string&gt;<br />#include &lt;vector&gt;<br /><br />using namespace std;<br /><br />int main() {<br />    vector&lt;string&gt; ss;<br />    ss.push_back("1");<br />    ss.push_back("2");<br />    ss.push_back("3");<br />    for (int i = 0; i &lt; (int)ss.size(); i++)<br />        cout &lt;&lt; ss[i] &lt;&lt; endl;<br />}<br />C:\Projects\STL&gt;cl /EHsc /nologo /W4 /MTd /Zi main.cpp<br />main.cpp<br /><br />C:\Projects\STL&gt;main<br />1<br />2<br />3</pre>
</div>
<p>Let&rsquo;s say you&rsquo;re using WinDbg 6.12.0002.633 from <a href="http://www.microsoft.com/en-us/download/details.aspx?id=8279" target="_blank">Microsoft Windows SDK for Windows 7 and .NET Framework 4</a>. If you set a breakpoint at the cout line (when the vector has data) and examine the vector with !stl, you&rsquo;ll get output similar to below if you use Visual C++ 2010 or 2012 to compile. Try a newer debugger package? WinDbg 6.2.9200.16384 from <a href="http://msdn.microsoft.com/en-us/windows/desktop/hh852363" target="_blank">Windows Software Development Kit (SDK) for Windows 8</a> produces the same result.</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">0:000&gt; !stl ss<br />TryToDumpAsVector(): Failed to g_ExtSymbols-&gt;GetFieldOffset( ModuleCollection, TypeIdCollection, FirstName, &amp;ElementOffset ) 0x80070057 [line 983]<br />    Unrecognized type 'std::vector&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt; &gt;' as an STL structure -- Defaulting to `dt -n (std::vector&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt; &gt;) 0x22fa78`<br />main!std::vector&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt; &gt;<br />   +0x000 _Myproxy         : 0x00361460 std::_Container_proxy<br />   +0x004 _Myfirst         : 0x003614f0 std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />   +0x008 _Mylast          : 0x00361550 std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />   +0x00c _Myend           : 0x00361550 std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />   +0x010 _Alval           : std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;</pre>
</div>
<p>However, try the debuggers on Visual C++ 2008 compiled binary and you&rsquo;ll get output similar to below, which is a whole lot nicer:</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">0:000&gt; !stl ss<br />    Element 0<br />[da 0x823798]<br />00823798  "1"<br />    Element 1<br />[da 0x8237b8]<br />008237b8  "2"<br />    Element 2<br />[da 0x8237d8]<br />008237d8  "3"</pre>
</div>
<p>As you can see, the !stl (and !std_map, etc.) extension is tightly coupled with the STL version that the extension was designed to support (offsets anyone?). By looking at the type information from various Visual C++ versions, you can see that the underlying STL implementation changes ever so slightly over time:</p>
<p>Visual C++ 2008:</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">0:000&gt; dt ss<br />Local var @ 0x18ff14 Type std::vector&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt; &gt;<br />   +0x000 _Myfirstiter     : (null) <br />   +0x004 _Alval           : std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;<br />   +0x008 _Myfirst         : 0x00823790 std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />   +0x00c _Mylast          : 0x008237f0 std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />   +0x010 _Myend           : 0x008237f0 std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;</pre>
</div>
<p>Visual C++ 2010:</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">0:000&gt; dt ss<br />Local var @ 0x22fa78 Type std::vector&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt; &gt;<br />   +0x000 _Myproxy         : 0x00361460 std::_Container_proxy<br />   +0x004 _Myfirst         : 0x003614f0 std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />   +0x008 _Mylast          : 0x00361550 std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />   +0x00c _Myend           : 0x00361550 std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />   +0x010 _Alval           : std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt;</pre>
</div>
<p>Visual C++ 2012:</p>
<div id="codeSnippetWrapper" style="margin: 20px 0px 10px; padding: 4px; border: 1px solid silver; width: 97.5%; text-align: left; line-height: 12pt; overflow: auto; font-family: consolas, courier, monospace; font-size: 8pt; cursor: text; direction: ltr; background-color: #f4f4f4;">
<pre id="codeSnippet" style="margin: 0em; padding: 0px; width: 100%; text-align: left; color: black; line-height: 12pt; overflow: visible; font-family: consolas, courier, monospace; font-size: 8pt; direction: ltr; background-color: #f4f4f4;">0:000&gt; dt ss<br />Local var @ 0xd4f938 Type std::vector&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;,std::allocator&lt;std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt; &gt; &gt;<br />   +0x000 _Myproxy         : 0x00e56418 std::_Container_proxy<br />   +0x004 _Myfirst         : 0x00e56858 std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />   +0x008 _Mylast          : 0x00e568ac std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;<br />   +0x00c _Myend           : 0x00e568ac std::basic_string&lt;char,std::char_traits&lt;char&gt;,std::allocator&lt;char&gt; &gt;</pre>
</div>
<p>There&rsquo;s little wonder why the extension sometimes work and sometimes doesn&rsquo;t. But instead of hunting down the right extension to dump the STL containers, how about understanding the underlying structures so that you can look at the data in WinDbg without an extension? These extensions, after all, look at the same piece of memory. For memory corruption cases, these extensions would probably barf anyway.</p>
<p>In the coming multi-part posts, I&rsquo;ll show you the steps to examine these containers yourself: <strong>vector</strong>, <strong>list</strong>, and <strong>map</strong>. Before that, I hope this post provides you with a little context on why anyone would want to do it by hand instead of using !stl.</p>
<p>For those who&rsquo;s interested, stay tuned~!!</p>
<hr />
<p>P.S. If you&rsquo;ve read this far you&rsquo;ve probably pulled your hair out more than once trying to debug STL containers with WinDbg. I&rsquo;d reckon you&rsquo;ve tried other extensions like <a href="http://www.bing.com/search?q=SDbgExt" target="_blank">SDbgExt</a> but those too may have suffered similar fate. Little known to a few people I encountered, Visual Studio has had the capability to <a href="http://msdn.microsoft.com/en-us/library/d5zhxt22.aspx" target="_blank">open dump files</a> since way before my hair started falling off.</p>
<p>Granted the things you could do after opening a dump file with older versions are, well, not that much, newer versions do provide incremental yet significant improvements. In terms of looking at values in STL containers, if that&rsquo;s all you need, maybe you can just open the dump file with Visual Studio and get comfy there:</p>
<p><a href="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/32/94/metablogapi/7848.VS2008STL_472EAD46.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-32-94-metablogapi/7848.VS2008STL_5F00_472EAD46.png"><img style="display: inline; background-image: none;" title="VS2008STL" src="https://msdnshared.blob.core.windows.net/media/MSDNBlogsFS/prod.evol.blogs.msdn.com/CommunityServer.Blogs.Components.WeblogFiles/00/00/00/32/94/metablogapi/1541.VS2008STL_thumb_15DFC2E6.png" original-url="http://blogs.msdn.com/cfs-file.ashx/__key/communityserver-blogs-components-weblogfiles/00-00-00-32-94-metablogapi/1541.VS2008STL_5F00_thumb_5F00_15DFC2E6.png" alt="VS2008STL" width="741" height="483" border="0" /></a></p>
<p>P.P.S. Over the years I occasionally ran into people who had to go through the same ordeal. Unfortunately I never seemed to pick myself up to write about it properly after I&rsquo;ve helped them out. Not sure what happened but I guess today is always a good day to start doing the right thing. At least now I bitbucket it here so that I don&rsquo;t need to re-remember these things when someone asks &ldquo;how do I dump an STL map in WinDbg" next time.</p>]]></content:encoded>
    </item>
  </channel>
</rss>