Tuesday, October 10, 2006

How to trace function calls with windbg

Have a closer look at the 'wt' command.
When using 'wt' you should not it carefully without specifying any of the -l, -m or -i options. In most cases it makes sense to use the -l option to limit the trace to a certain depth (e.g.: 2 to 5) or to limit it to a certain modult with the -m option.

Output can look like this:

Attach to notepad.exe

Set a break point to...
0:001> bp notepad!FileDragOpen
0:001> g

Now drag a text file into notepad, the breakpoint will hit...

Breakpoint 1 hit
eax=00000000 ebx=00000000 ecx=0007fdb0 edx=7c90eb94 esi=7ca10702 edi=00000000
eip=0100337e esp=0007fdb8 ebp=0007fdc0 iopl=0 nv up ei pl zr na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000246
notepad!FileDragOpen:
0100337e 8bff mov edi,edi

0:000> wt -l 2
Tracing notepad!FileDragOpen to return address 01003416
7 0 [ 0] notepad!FileDragOpen
155 0 [ 1] notepad!CheckSave
24 0 [ 2] USER32!SendMessageW
165 24 [ 1] notepad!CheckSave
5 0 [ 2] notepad!__security_check_cookie
167 29 [ 1] notepad!CheckSave
18 196 [ 0] notepad!FileDragOpen
19 0 [ 1] kernel32!CreateFileW
96 0 [ 2] ntdll!RtlInitUnicodeString
33 96 [ 1] kernel32!CreateFileW
32 0 [ 2] kernel32!BaseIsThisAConsoleName
42 128 [ 1] kernel32!CreateFileW
30 0 [ 2] ntdll!RtlDosPathNameToNtPathName_U
133 158 [ 1] kernel32!CreateFileW
4 0 [ 2] ntdll!NtCreateFile
140 162 [ 1] kernel32!CreateFileW
79 0 [ 2] ntdll!RtlFreeHeap
147 241 [ 1] kernel32!CreateFileW
14 0 [ 2] ntdll!RtlFreeHeap
155 255 [ 1] kernel32!CreateFileW
17 0 [ 2] kernel32!SetLastError
163 272 [ 1] kernel32!CreateFileW
24 631 [ 0] notepad!FileDragOpen
3 0 [ 1] notepad!LoadFile
19 0 [ 2] notepad!_SEH_prolog
20 19 [ 1] notepad!LoadFile
91 0 [ 2] kernel32!GetFileInformationByHandle
30 110 [ 1] notepad!LoadFile
4 0 [ 2] USER32!NtUserSetCursor
41 114 [ 1] notepad!LoadFile
67 0 [ 2] kernel32!CreateFileMappingW
50 181 [ 1] notepad!LoadFile
12 0 [ 2] kernel32!MapViewOfFile
53 193 [ 1] notepad!LoadFile
24 0 [ 2] kernel32!CloseHandle
57 217 [ 1] notepad!LoadFile
24 0 [ 2] kernel32!CloseHandle
75 241 [ 1] notepad!LoadFile
12 0 [ 2] notepad!IsInputTextUnicode
81 253 [ 1] notepad!LoadFile
429224 0 [ 2] notepad!IsTextUTF8

430213 instructions were executed in 430212 events (0 from other threads)

Function Name Invocations MinInst MaxInst AvgInst
USER32!NtUserSetCursor 1 4 4 4
USER32!SendMessageW 1 24 24 24
kernel32!BaseIsThisAConsoleName 1 32 32 32
kernel32!CloseHandle 2 24 24 24
kernel32!CreateFileMappingW 1 67 67 67
kernel32!CreateFileW 1 163 163 163
kernel32!GetFileInformationByHandle 1 91 91 91
kernel32!MapViewOfFile 1 12 12 12
kernel32!SetLastError 1 17 17 17
notepad!CheckSave 1 167 167 167
notepad!FileDragOpen 1 24 24 24
notepad!IsInputTextUnicode 1 12 12 12
notepad!IsTextUTF8 1 429224 429224 429224
notepad!LoadFile 1 81 81 81
notepad!_SEH_prolog 1 19 19 19
notepad!__security_check_cookie 1 5 5 5
ntdll!NtCreateFile 1 4 4 4
ntdll!RtlDosPathNameToNtPathName_U 1 30 30 30
ntdll!RtlFreeHeap 2 14 79 46
ntdll!RtlInitUnicodeString 1 96 96 96

0 system calls were executed

ps.: This should hide most of the OS stuff, when you are just interested in your own code:
wt -i MSVCP60 -i OLEAUT32 -i SHLWAPI -i USER32 -i kernel32 -i msvcrt -i msxml4 -i ntdll

How to break on VB6 run time errors

In order to detect VB6 run time errors you need to set a break point to MSVBVM60!EbRaiseExceptionCode and MSVBVM60!EbRaiseException:

bp MSVBVM60!EbRaiseExceptionCode
bp MSVBVM60!EbRaiseException

Or even simpler with e wildcard:
bm /a MSVBVM60!EbRaiseException*