Over a million developers have joined DZone.
{{announcement.body}}
{{announcement.title}}

Obscure WinDbg Commands, Part 3

DZone's Guide to

Obscure WinDbg Commands, Part 3

·
Free Resource

In today’s installment, we’ll take a look at two commands that make it easier to trace through program execution.

The first command is wt, which traces through all the function calls performed in a certain code path and formats nice statistics illustrating what happened during that function’s execution. wthas a bunch of options that I won’t be showing here, but the general idea is that you let it trace through a lot of unfamiliar code and display statistics on what was going on in that code.

For example, here I used a switch to filter out internal calls inside ntdll, which produces a much tighter output and still shows the general tree of function calls and statistics at the end: 

0:000> wt -i ntdll 
Tracing SillyThreadPool!wmain to return address 009a1a49 
   63     0 [  0] SillyThreadPool!wmain 
    5     0 [  1]   KERNEL32!OutputDebugStringWStub 
   16     0 [  1]   KERNELBASE!OutputDebugStringW 
  376     0 [  2]     ntdll!RtlInitUnicodeStringEx 
   25   376 [  1]   KERNELBASE!OutputDebugStringW 
   51     0 [  2]     ntdll!RtlUnicodeStringToAnsiString 
   31   427 [  1]   KERNELBASE!OutputDebugStringW 
    3     0 [  2]     KERNELBASE!OutputDebugStringA 
   22     0 [  3]       KERNELBASE!_SEH_prolog4_GS 
  369    22 [  2]     KERNELBASE!OutputDebugStringA 
   28     0 [  3]       KERNELBASE!RaiseException 
    1     0 [  4]         KERNELBASE!memcpy 
   32     0 [  4]         ntdll!memcpy 
   33    33 [  3]       KERNELBASE!RaiseException 

998 instructions were executed in 997 events (0 from other threads) 

Function Name                     Invocations MinInst MaxInst AvgInst 
KERNEL32!OutputDebugStringWStub             1       5       5       5 
KERNELBASE!OutputDebugStringA               1     369     369     369 
KERNELBASE!OutputDebugStringW               1      31      31      31 
KERNELBASE!RaiseException                   1      33      33      33 
KERNELBASE!_SEH_prolog4_GS                  1      22      22      22 
KERNELBASE!memcpy                           1       1       1       1 
SillyThreadPool!wmain                       1      63      63      63 
ntdll!RtlInitUnicodeStringEx                1     376     376     376 
ntdll!RtlRaiseException                     1      15      15      15 
ntdll!RtlUnicodeStringToAnsiString          1      51      51      51 
ntdll!memcpy                                1      32      32      32 
0 system calls were executed

Here, on the other hand, I asked for complete statistics, but no details on every and each function call:

0:000> wt -nc 
Tracing SillyThreadPool!wmain to return address 009a1a49 
12975 instructions were executed in 12974 events (0 from other threads) 

Function Name                        Invocations MinInst MaxInst AvgInst 
0x77c521dc                                    12       1       1       1 
KERNEL32!CreateEventW                          1       1       1       1 
KERNEL32!CreateThreadStub                     10       2      16      14 
KERNEL32!GetConsoleMode                        1       1       1       1 
KERNEL32!OutputDebugStringWStub                1       5       5       5 
KERNELBASE!BaseFormatObjectAttributes          10      20      20      20 
KERNELBASE!ConsoleCallServer                   1      15      15      15 
KERNELBASE!ConsoleCallServerGeneric            1      72      72      72 
KERNELBASE!CreateEventExW                      1      33      33      33 
KERNELBASE!CreateEventW                        1      14      14      14 
KERNELBASE!CreateRemoteThreadEx                20       8     135      65 
KERNELBASE!GetConsoleMode                      1      11      11      11 
KERNELBASE!OutputDebugStringA                  1     372     372     372 
KERNELBASE!OutputDebugStringW                  1      41      41      41 
KERNELBASE!RaiseException                      3       1      33      13 
KERNELBASE!_SEH_epilog4                       11      11      11      11 
KERNELBASE!_SEH_epilog4_GS                    11       4       4       4 
KERNELBASE!_SEH_prolog4_GS                    10      22      22      22 
KERNELBASE!__security_check_cookie            12       3       3       3 
KERNELBASE!memcpy                              1       1       1       1 
MSVCR110D!__iob_func                           1       5       5       5 
MSVCR110D!__lock_fhandle                       1      49      49      49 
MSVCR110D!_fgetchar                            1       8       8       8 
MSVCR110D!_filbuf                              1      54      54      54 
MSVCR110D!_fileno                              2      18      18      18 
MSVCR110D!_isatty                              1      29      29      29 
MSVCR110D!_lock                                1      11      11      11 
MSVCR110D!_lock_file                           1      24      24      24 
MSVCR110D!_read                                1      80      80      80 
MSVCR110D!_read_nolock                         1     137     137     137 
MSVCR110D!getc                                 1     103     103     103 
MSVCR110D!getchar                              1       3       3       3 
SillyThreadPool!ILT+330(__RTC_CheckEsp)       11       1       1       1 
SillyThreadPool!_RTC_CheckEsp                 11       2       2       2 
SillyThreadPool!wmain                          2      71     154     112 
ntdll!IdnaMemFree                              1      10      10      10 
ntdll!NtAllocateVirtualMemory                  1       1       1       1 
ntdll!NtCreateEvent                            1       2       2       2 
ntdll!NtCreateThreadEx                        19       1       2       1 
ntdll!NtDeviceIoControlFile                    1       2       2       2 
ntdll!NtRaiseException                         1       2       2       2 
ntdll!NtdllpAllocateStringRoutine              1      10      10      10 
ntdll!RtlAddRefActivationContext               9       8       8       8 
ntdll!RtlAllocateHeap                          2      63      63      63 
ntdll!RtlCaptureContext                        1      10      10      10 
ntdll!RtlCompareMemory                         1      18      18      18 
ntdll!RtlCompareMemoryUlong                    2    1006    1034    1020 
ntdll!RtlDebugAllocateHeap                     2       6     111      58 
ntdll!RtlDebugFreeHeap                         2       6      66      36 
ntdll!RtlEnterCriticalSection                  4      14      14      14 
ntdll!RtlFillMemoryUlong                       3      28    1031     687 
ntdll!RtlFreeAnsiString                        1      15      15      15 
ntdll!RtlFreeHeap                              2      44      44      44 
ntdll!RtlGetNtGlobalFlags                      4       3       3       3 
ntdll!RtlInitUnicodeStringEx                   1     376     376     376 
ntdll!RtlLeaveCriticalSection                  2      23      23      23 
ntdll!RtlQueryInformationActivationContext    18       5      95      50 
ntdll!RtlRaiseException                        1      15      15      15 
ntdll!RtlUnicodeStringToAnsiString             2       5      51      28 
ntdll!RtlUnicodeToMultiByteN                   1     337     337     337 
ntdll!RtlpAllocateHeap                         3       3     298     112 
ntdll!RtlpCaptureContext                       1      17      17      17 
ntdll!RtlpCheckBusyBlockTail                   1      61      61      61 
ntdll!RtlpCheckHeapSignature                   2      14      14      14 
ntdll!RtlpCoalesceFreeBlocks                   1     136     136     136 
ntdll!RtlpCreateSplitBlock                     1     119     119     119 
ntdll!RtlpFindEntry                            3      26      31      29 
ntdll!RtlpFreeHeap                             3       5     205      81 
ntdll!RtlpGetActivationContextData             9      25      25      25 
ntdll!RtlpGetExtraStuffPointer                 2      11      11      11 
ntdll!RtlpHeapAddListEntry                     2      41      41      41 
ntdll!RtlpHeapFindListLookupEntry              3      55      96      68 
ntdll!RtlpHeapFreeListCompare                 10      32      32      32 
ntdll!RtlpHeapRemoveListEntry                  2      41      41      41 
ntdll!RtlpQueryInformationActivationContextBasi9      32      32      32 
ntdll!RtlpValidateHeap                         3      28      28      28 
ntdll!RtlpValidateHeapEntry                    1      75      75      75 
ntdll!RtlpValidateHeapHeaders                  5       9       9       9 
ntdll!_SEH_epilog4                             16      11      11      11 
ntdll!_SEH_prolog4                             16      21      21      21 
ntdll!__security_check_cookie                  2       3       3       3 
ntdll!memcpy                                   1      32      32      32

Whew! Lots of information here, and lots of functions that you wouldn’t even guess are executed by your code.

The second command I’d like to show you today is a bit odd: <command>; z(<expression>). This command will execute the specified command while the specified conditional expression is true.This is handy for stepping through code, setting poor-man’s conditional breakpoints, and even executing simple logical loops without the help of the .for and .foreach tokens.

For example, suppose I am inside a loop and I want to trace the loop’s execution until the loop iteration variable (i) becomes equal to 10. I can do the following:

p; z(@@($!i != 10))

The command to execute is p, which steps through the loop’s execution (without stepping into subroutine calls). The expression requires that the iteration variable is not equal to 10. The extra @@ signs and $! signs are required to force the C++ expression evaluator and force i to resolve as a local variable.

I am posting short links and updates on Twitter as well as on this blog. You can follow me: @goldshtn

Topics:

Published at DZone with permission of Sasha Goldshtein, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

THE DZONE NEWSLETTER

Dev Resources & Solutions Straight to Your Inbox

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.

X

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}