Special Command—Tracing Applications Using wt
wt [WatchOptions] [= StartAddress] [EndAddress]
Transcribing the WinDbg documentation, this command runs through the whole function and then displays statistics when executed at the beginning of a function call. Thus, this command can be used just when doing live debugging, not post mortem debugging (dump analysis).
Think about Watch and Trace.
The WinDbg help file describes all options for WatchOptions. Usually we use the simplest form, not these options.
To demonstrate this command, let’s use this simple Visual C++ application that recursively calculates the Fibonacci from a specific number:
#include "stdafx.h"
using namespace std;
// Recursive function.
unsigned FiboRecursive(unsigned n, int nNum = 0)
{
if(n <= 1)
{
return n;
}
return FiboRecursive(n - 1, 1) + FiboRecursive(n - 2, 2);
}
int _tmain(int argc, _TCHAR* argv[])
{
cout << FiboRecursive(5) << endl;
return 0;
}
Now we run the application from WinDbg and insert a breakpoint in the beginning of _tmain() .
After hitting the breakpoint, we disassemble the function:
0:000> uf Fibo!wmain
Fibo!wmain [c:\development\my tools\book\fibo\fibo\fibo.cpp @ 20]:
20 001b1440 55 push ebp
20 001b1441 8bec mov ebp,esp
20 001b1443 81ecc0000000 sub esp,0C0h
20 001b1449 53 push ebx
20 001b144a 56 push esi
20 001b144b 57 push edi
20 001b144c 8dbd40ffffff lea edi,[ebp-0C0h]
20 001b1452 b930000000 mov ecx,30h
20 001b1457 b8cccccccc mov eax,0CCCCCCCCh
20 001b145c f3ab rep stos dword ptr es:[edi]
21 001b145e 8bf4 mov esi,esp
21 001b1460 a198821b00 mov eax,dword ptr [Fibo!_imp_?endlstdYAAAV?$basic_ostreamDU?$char_traitsDstd (001b8298)]
21 001b1465 50 push eax
21 001b1466 6a00 push 0
21 001b1468 6a05 push 5
21 001b146a e89bfbffff call Fibo!ILT+5(?FiboRecursiveYAIIHZ) (001b100a)
21 001b146f 83c408 add esp,8
21 001b1472 8bfc mov edi,esp
21 001b1474 50 push eax
21 001b1475 8b0d90821b00 mov ecx,dword ptr [Fibo!_imp_?coutstd (001b8290)]
21 001b147b ff1594821b00 call dword ptr [Fibo!_imp_??6?$basic_ostreamDU?$char_traitsDstdstdQAEAAV01IZ (001b8294)]
21 001b1481 3bfc cmp edi,esp
21 001b1483 e8d1fcffff call Fibo!ILT+340(__RTC_CheckEsp) (001b1159)
21 001b1488 8bc8 mov ecx,eax
21 001b148a ff159c821b00 call dword ptr [Fibo!_imp_??6?$basic_ostreamDU?$char_traitsDstdstdQAEAAV01P6AAAV01AAV01ZZ (001b829c)]
21 001b1490 3bf4 cmp esi,esp
21 001b1492 e8c2fcffff call Fibo!ILT+340(__RTC_CheckEsp) (001b1159)
23 001b1497 33c0 xor eax,eax
24 001b1499 5f pop edi
24 001b149a 5e pop esi
24 001b149b 5b pop ebx
24 001b149c 81c4c0000000 add esp,0C0h
24 001b14a2 3bec cmp ebp,esp
24 001b14a4 e8b0fcffff call Fibo!ILT+340(__RTC_CheckEsp) (001b1159)
24 001b14a9 8be5 mov esp,ebp
24 001b14ab 5d pop ebp
24 001b14ac c3 ret
Let’s use the address right before the recursive function call as the Start address and the address right after it as the End address of wt. Note the “ = ” right before the first address.
0:000> wt =001b1468 001b146f
2 0 [ 0] Fibo!wmain
1 0 [ 1] Fibo!ILT+5(?FiboRecursiveYAIIHZ)
64 0 [ 1] Fibo!FiboRecursive
1 0 [ 2] Fibo!ILT+5(?FiboRecursiveYAIIHZ)
64 0 [ 2] Fibo!FiboRecursive
1 0 [ 3] Fibo!ILT+5(?FiboRecursiveYAIIHZ)
64 0 [ 3] Fibo!FiboRecursive
1 0 [ 4] Fibo!ILT+5(?FiboRecursiveYAIIHZ)
64 0 [ 4] Fibo!FiboRecursive
1 0 [ 5] Fibo!ILT+5(?FiboRecursiveYAIIHZ)
67 0 [ 5] Fibo!FiboRecursive
1 0 [ 6] Fibo!ILT+340(__RTC_CheckEsp)
2 0 [ 6] Fibo!_RTC_CheckEsp
70 3 [ 5] Fibo!FiboRecursive
71 74 [ 4] Fibo!FiboRecursive
1 0 [ 5] Fibo!ILT+5(?FiboRecursiveYAIIHZ)
67 0 [ 5] Fibo!FiboRecursive
1 0 [ 6] Fibo!ILT+340(__RTC_CheckEsp)
2 0 [ 6] Fibo!_RTC_CheckEsp
70 3 [ 5] Fibo!FiboRecursive
79 148 [ 4] Fibo!FiboRecursive
1 0 [ 5] Fibo!ILT+340(__RTC_CheckEsp)
2 0 [ 5] Fibo!_RTC_CheckEsp
82 151 [ 4] Fibo!FiboRecursive
71 234 [ 3] Fibo!FiboRecursive
1 0 [ 4] Fibo!ILT+5(?FiboRecursiveYAIIHZ)
67 0 [ 4] Fibo!FiboRecursive
1 0 [ 5] Fibo!ILT+340(__RTC_CheckEsp)
2 0 [ 5] Fibo!_RTC_CheckEsp
70 3 [ 4] Fibo!FiboRecursive
79 308 [ 3] Fibo!FiboRecursive
1 0 [ 4] Fibo!ILT+340(__RTC_CheckEsp)
2 0 [ 4] Fibo!_RTC_CheckEsp
82 311 [ 3] Fibo!FiboRecursive
71 394 [ 2] Fibo!FiboRecursive
1 0 [ 3] Fibo!ILT+5(?FiboRecursiveYAIIHZ)
64 0 [ 3] Fibo!FiboRecursive
1 0 [ 4] Fibo!ILT+5(?FiboRecursiveYAIIHZ)
67 0 [ 4] Fibo!FiboRecursive
1 0 [ 5] Fibo!ILT+340(__RTC_CheckEsp)
2 0 [ 5] Fibo!_RTC_CheckEsp
70 3 [ 4] Fibo!FiboRecursive
71 74 [ 3] Fibo!FiboRecursive
1 0 [ 4] Fibo!ILT+5(?FiboRecursiveYAIIHZ)
67 0 [ 4] Fibo!FiboRecursive
1 0 [ 5] Fibo!ILT+340(__RTC_CheckEsp)
2 0 [ 5] Fibo!_RTC_CheckEsp
70 3 [ 4] Fibo!FiboRecursive
79 148 [ 3] Fibo!FiboRecursive
1 0 [ 4] Fibo!ILT+340(__RTC_CheckEsp)
2 0 [ 4] Fibo!_RTC_CheckEsp
82 151 [ 3] Fibo!FiboRecursive
79 628 [ 2] Fibo!FiboRecursive
1 0 [ 3] Fibo!ILT+340(__RTC_CheckEsp)
2 0 [ 3] Fibo!_RTC_CheckEsp
82 631 [ 2] Fibo!FiboRecursive
71 714 [ 1] Fibo!FiboRecursive
1 0 [ 2] Fibo!ILT+5(?FiboRecursiveYAIIHZ)
64 0 [ 2] Fibo!FiboRecursive
1 0 [ 3] Fibo!ILT+5(?FiboRecursiveYAIIHZ)
64 0 [ 3] Fibo!FiboRecursive
1 0 [ 4] Fibo!ILT+5(?FiboRecursiveYAIIHZ)
67 0 [ 4] Fibo!FiboRecursive
1 0 [ 5] Fibo!ILT+340(__RTC_CheckEsp)
2 0 [ 5] Fibo!_RTC_CheckEsp
70 3 [ 4] Fibo!FiboRecursive
71 74 [ 3] Fibo!FiboRecursive
1 0 [ 4] Fibo!ILT+5(?FiboRecursiveYAIIHZ)
67 0 [ 4] Fibo!FiboRecursive
1 0 [ 5] Fibo!ILT+340(__RTC_CheckEsp)
2 0 [ 5] Fibo!_RTC_CheckEsp
70 3 [ 4] Fibo!FiboRecursive
79 148 [ 3] Fibo!FiboRecursive
1 0 [ 4] Fibo!ILT+340(__RTC_CheckEsp)
2 0 [ 4] Fibo!_RTC_CheckEsp
82 151 [ 3] Fibo!FiboRecursive
71 234 [ 2] Fibo!FiboRecursive
1 0 [ 3] Fibo!ILT+5(?FiboRecursiveYAIIHZ)
67 0 [ 3] Fibo!FiboRecursive
1 0 [ 4] Fibo!ILT+340(__RTC_CheckEsp)
2 0 [ 4] Fibo!_RTC_CheckEsp
70 3 [ 3] Fibo!FiboRecursive
79 308 [ 2] Fibo!FiboRecursive
1 0 [ 3] Fibo!ILT+340(__RTC_CheckEsp)
2 0 [ 3] Fibo!_RTC_CheckEsp
82 311 [ 2] Fibo!FiboRecursive
79 1108 [ 1] Fibo!FiboRecursive
1 0 [ 2] Fibo!ILT+340(__RTC_CheckEsp)
2 0 [ 2] Fibo!_RTC_CheckEsp
82 1111 [ 1] Fibo!FiboRecursive
1196 instructions were executed in 1195 events (0 from other threads)
Function Name Invocations MinInst MaxInst AvgInst
Fibo!FiboRecursive 15 70 82 75
Fibo!ILT+340(__RTC_CheckEsp) 15 1 1 1
Fibo!ILT+5(?FiboRecursiveYAIIHZ) 15 1 1 1
Fibo!_RTC_CheckEsp 15 2 2 2
Fibo!wmain 1 2 2 2
0 system calls were executed
eax=00000005 ebx=7efde000 ecx=00000000 edx=00000001 esi=00000000 edi=00000000
eip=001b146f esp=0045f914 ebp=0045f964 iopl=0 nv up ei pl zr na pe nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000246
Fibo!wmain+0x2f:
001b146f 83c408 add esp,8
Notice that the first number right below the command specifies the number of instructions that were executed, the second number specifies the number of instructions executed by child calls of the function, and the third number (in brackets) is the depth of the function in the stack.
MinInst, MaxInst and AvgInst mean the number of instructions by call.
Comments
- Anonymous
January 13, 2010
here is a post describing both using wt command and logger utility to trace sys calls: http://rxwen.blogspot.com/2009/08/trace-system-calls.html