Debugger commands (dt, ??) that make my life easier (part 4)
Today I will cover how to look at type information from the command line of windbg/kd. You can do all of this in the UI with a mouse, but that takes too long ;). I like to keep my hands on the keyboard and not move around. More importantly, by learning the command line way, you can embed commands to execute in a breakpoint statement so that every time the bp is hit, you get all of your information displayed for you without any additional typing. I am going to cover the "dt" and "??" commands.
Here is a C++ program which I will use in demonstrating these commands. Before executing any of the commands, I set a bp on the "return 0;" statement and I am now at that point in the program.
#include <windows.h>
#include <Stdio.h>
typedef struct _BELOW {
_BELOW() : One(1) {}
ULONG One;
} BELOW, *PBELOW;
typedef struct _TOP {
_TOP(PBELOW Below) : Three(3), Pointer(Below) { Embedded.Two = 2; }
struct {
ULONG Two;
} Embedded;
PBELOW Pointer;
ULONG Three;
} TOP, *PTOP;
int _cdecl main(int argc, char *argv[])
{
BELOW below;
TOP top(&below);
ULONG values[4], i;
for (i = 0; i < sizeof(values)/sizeof(values[0]); i++) { values[i] = i+1; }
return 0;
}
dt (which stands for display type) is a very powerful command which can perform a lot of expression evaluation for you. You can have it simply dump a local variable [1]. You can refine the output to a specific field [2] or substructure [3] and [4]. Note the difference between the output of [3] and [4], by including the ".", dt will dump all subfields of the structure.
[1] 0:000> dt top
+0x000 Embedded : _TOP::<unnamed-tag>
+0x004 Pointer : 0x01002034 _BELOW
+0x008 Three : 3
[2] 0:000> dt top Three
+0x008 Three : 3
[3] 0:000> dt top Embedded
+0x000 Embedded : _TOP::<unnamed-tag>
[4] 0:000> dt top Embedded.
+0x000 Embedded :
+0x000 Two : 2
Even better, dt iterate over an array [5] and can follow pointers from the structure [6]. But what if you want to dump all the fields of the pointer? dt top Pointer->. doesn't work (because it is not a valid C expression). The "??" command comes to the rescue here; you can use it to evaluate the pointer value [7]. Not only will ?? evaluate C or C++ expresssions that contain variables, it can also evaluate expressions using types [8].
[5] 0:000> dt -a values
Local var @ 0x6ff68 Type unsigned long[]
[0] @ 0006ff68
---------------------------------------------
1
[1] @ 0006ff6c
---------------------------------------------
2
[2] @ 0006ff70
---------------------------------------------
3
[3] @ 0006ff74
---------------------------------------------
4
[6] 0:000> dt top Pointer->One
+0x004 Pointer :
+0x000 One : 1
[7] 0:000> ?? top.Pointer
struct _BELOW * 0x01002034
+0x000 One : 1
[8] 0:000> ?? sizeof(top)
unsigned int 0xc
0:000> ?? sizeof(_TOP)
unsigned int 0xc
This is just the tip of the iceburg with these commands. I suggest that you open up the debugger help (c:\debuggers\debugger.chm) and look up these commands and their syntax...it is pretty powerful stuff!
Comments
- Anonymous
March 22, 2006
dump/display type, surely? Or is it historically dump tmp, and corrected to display type? - Anonymous
March 22, 2006
fixed. thanks for catching the typo, i meant type. - Anonymous
March 22, 2006
darn... I thought there'd be some interesting history there.
Keep up the good blogging! - Anonymous
March 23, 2006
history of what? the debuggers or WDM?