Showing posts with label map. Show all posts
Showing posts with label map. Show all posts

Saturday, December 7, 2013

Debugging Map using Windbg

Here is the script which we can use for displaying the MAP:

.if ($sicmp("${$arg1}", "-n") == 0) {
    .if (@@(@$t0->_Isnil) == 0) {
        .if (@$t2 == 1) {
            .printf /D "%p\n", @$t0, @$t0
            .printf "key = "
            ?? @$t0->_Myval.first
            .printf "value = "
            ?? @$t0->_Myval.second
        } .else {
            r? $t9 = @$t0->_Myval
            command
        }
    }

    $$ Recurse into _Left, _Right unless they point to the root of the tree
    .if (@@(@$t0->_Left) != @@(@$t1)) {
        .push /r /q
        r? $t0 = @$t0->_Left
        $$>a< ${$arg0} -n
        .pop /r /q
    }
    .if (@@(@$t0->_Right) != @@(@$t1)) {
        .push /r /q
        r? $t0 = @$t0->_Right
        $$>a< ${$arg0} -n
        .pop /r /q
    }
} .else {
    r? $t0 = ${$arg1}

    .if (${/d:$arg2}) {
        .if ($sicmp("${$arg2}", "-c") == 0) {
            r $t2 = 0
            aS ${/v:command} "${$arg3}"
        }
    } .else {
        r $t2 = 1
        aS ${/v:command} " "
    }

    .printf "size = %d\n", @@(@$t0._Mysize)
   
    r? $t0 = @$t0._Myhead->_Parent
    r? $t1 = @$t0->_Parent

    $$>a< ${$arg0} -n

    ad command
}

traverse_map.script
A WinDbg script that traverses std::map objects.

Usage:

$$>a< traverse_map.script [-c "cmd"]

where cmd can reference @$t9, e.g. "?? @$t9.second" (this is the pair held by the map) and can also reference @$t0, which is the actual tree node pointer.

Examples:

$$>a< traverse_map.script my_map -c ".block { .echo ----; ?? @$t9.first; ?? @$t9.second; }"
$$>a< traverse_map.script m -c ".block { .if (@@(@$t9.first) == 8) { .echo ----; ?? @$t9.second } }"
$$>a< traverse_map.script my_map

Sample Program:-

class MapTest
{
public:
void PopulateMap();
private:
map m_Map1;
map m_Map2;
};

void MapTest::PopulateMap()
{
m_Map1[0] = 99;
m_Map1[1] = 100;

m_Map2[0] = wstring(L"Hello");
m_Map2[1] = wstring(L"World");

//stop the debugger here
__asm int 3
}

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

map  mm;
mm[1] = 1;
mm[2] = 2;

//stop the debugger
__asm int 3
MapTest mt;
mt.PopulateMap();
}


TestApp!wmain+0x8a:
0125203a 8d4d94          lea     ecx,[ebp-6Ch]
0:000> $$>a<C:\Users\ankurm\Desktop\traverse_map1.script mm
size = 2
002e8a48
key = int 0n1
value = int 0n1
002e8aa0
key = int 0n2
value = int 0n2
0:000> g
(2f68.2260): Break instruction exception - code 80000003 (first chance)
eax=00000000 ebx=7efde000 ecx=8c2cadb9 edx=65a7d238 esi=001af620 edi=001af784
eip=01251f26 esp=001af620 ebp=001af790 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
TestApp!MapTest::PopulateMap+0x186:
01251f26 cc              int     3
0:000> dv
           this = 0x001af8ec
0:000> $$>a<C:\Users\ankurm\Desktop\traverse_map1.script this->m_Map1
size = 2
002e8bc0
key = int 0n0
value = int 0n99
002e8c18
key = int 0n1
value = int 0n100
0:000> $$>a<C:\Users\ankurm\Desktop\traverse_map1.script this->m_Map2
size = 2
002e8c70
key = int 0n0
value = class std::basic_string,std::allocator >
   +0x000 _Myfirstiter     : (null) 
   +0x004 _Alval           : std::allocator
   =01240000 npos             : 0x905a4d
   +0x008 _Bx              : std::basic_string,std::allocator >::_Bxty
   +0x018 _Mysize          : 5
   +0x01c _Myres           : 7
002e8ce0
key = int 0n1
value = class std::basic_string,std::allocator >
   +0x000 _Myfirstiter     : (null) 
   +0x004 _Alval           : std::allocator
   =01240000 npos             : 0x905a4d
   +0x008 _Bx              : std::basic_string,std::allocator >::_Bxty
   +0x018 _Mysize          : 5
   +0x01c _Myres           : 7


References:-
http://blogs.microsoft.co.il/sasha/2013/07/25/displaying-and-searching-stdmap-contents-in-windbg/
https://github.com/goldshtn/windbg-extensions