Windbg提供比VS2008丰富很多的调试命令,尤其是调试多线程程序。
今天试着怎么使用源代码方式调试。为了说明调试命令,《C++标准库》一书里的例子做示范。
// testcast.cpp #include <stdio.h> #include <iostream> struct A { virtual void test() { printf_s("in A "); } }; struct B : A { virtual void test() { printf_s("in B "); } void test2() { printf_s("test2 in B "); } }; struct C : B { virtual void test() { printf_s("in C "); } void test2() { printf_s("test2 in C "); } }; void Globaltest(A& a) { try { C &c = dynamic_cast<C&>(a); printf_s("in GlobalTest "); } catch(std::bad_cast) { printf_s("Can't cast to C "); } } int main() { A *pa = new C; A *pa2 = new B; pa->test(); B * pb = dynamic_cast<B *>(pa); if (pb) pb->test2(); C * pc = dynamic_cast<C *>(pa2); if (pc) pc->test2(); C ConStack; Globaltest(ConStack); // will fail because B knows nothing about C B BonStack; Globaltest(BonStack); }
使用命令编译并连接
cl.exe testcast.cpp /Zi
link testcast.obj /DEBUG
确保系统已经安装了windbg和symbol。
在命令行窗体,cd testcast.exe所在目录
Windbg testcast.exe
打开Windbg窗体,进入到用户模式调试
命令行交互如下(蓝色为注释):
Microsoft (R) Windows Debugger Version 6.2.9200.20512 AMD64
Copyright (c) Microsoft Corporation. All rights reserved.
CommandLine: testcast.exe
Symbol search path is: C:Symbols;d:CodeExerciseC++
C:Symbols为Windows Symbols目录,使用.symfix 可以恢复sympath为微软网站上的symbol存储位置
.sympath 查看当前symbol目录
.sympath+ D:CodeExerciseC++ 将“D:CodeExerciseC++ ”添加到symbol搜索路径中
.srcpath 查看源码搜索路径
.srcpath+ D:CodeExerciseC++ 将“D:CodeExerciseC++ ” 添加到源码搜索路径中
Executable search path is:
ModLoad: 00000000`00ac0000 00000000`00af1000 testcast.exe
ModLoad: 00000000`77b40000 00000000`77cec000 ntdll.dll
ModLoad: 00000000`77d20000 00000000`77ea0000 ntdll32.dll
ModLoad: 00000000`73e80000 00000000`73ebf000 C:WindowsSYSTEM32wow64.dll
ModLoad: 00000000`73e20000 00000000`73e7c000 C:WindowsSYSTEM32wow64win.dll
ModLoad: 00000000`73e10000 00000000`73e18000 C:WindowsSYSTEM32wow64cpu.dll
(1a58.b40): Break instruction exception - code 80000003 (first chance)
*** ERROR: Symbol file could not be found. Defaulted to export symbols for ntdll.dll -
ntdll!CsrSetPriorityClass+0x40:
00000000`77bf0fe0 cc int 3
0:000> bl bl用于显示断点列表
0:000> bp testcast!main 在testcast模块的main函数开头下断点
*** WARNING: Unable to verify checksum for testcast.exe
0:000> bp testcast!Globaltest 在testcast模块的Globaltest函数开头下断点
0:000> g 执行
ModLoad: 00000000`77920000 00000000`77a3f000 WOW64_IMAGE_SECTION
ModLoad: 00000000`75930000 00000000`75a40000 WOW64_IMAGE_SECTION
ModLoad: 00000000`77920000 00000000`77a3f000 NOT_AN_IMAGE
ModLoad: 00000000`77a40000 00000000`77b3a000 NOT_AN_IMAGE
ModLoad: 00000000`75930000 00000000`75a40000 C:Windowssyswow64kernel32.dll
ModLoad: 00000000`758e0000 00000000`75927000 C:Windowssyswow64KERNELBASE.dll
(1a58.b40): WOW64 breakpoint - code 4000001f (first chance)
First chance exceptions are reported before any exception handling.
This exception may be expected and handled.
*** ERROR: Symbol file could not be found. Defaulted to export symbols for ntdll32.dll -
ntdll32!LdrVerifyImageMatchesChecksum+0x6ce:
77dc0e0b cc int 3
0:000:x86> g
Breakpoint 0 hit
testcast!main:
00ac1100 55 push ebp
0:000:x86> p 单步执行
testcast!main+0x6:
00ac1106 6a04 push 4
0:000:x86> t 单步跟踪
testcast!operator new:
00ac1fd9 8bff mov edi,edi
0:000:x86> t
testcast!operator new+0x2:
00ac1fdb 55 push ebp
0:000:x86> t
testcast!operator new+0x3:
00ac1fdc 8bec mov ebp,esp
0:000:x86> p
testcast!operator new+0x5:
00ac1fde 83ec10 sub esp,10h
0:000:x86> p
testcast!operator new+0x8:
00ac1fe1 eb0d jmp testcast!operator new+0x17 (00ac1ff0)
0:000:x86> p
testcast!operator new+0x17:
00ac1ff0 ff7508 push dword ptr [ebp+8] ss:002b:003bfd20=04000000
0:000:x86> p
testcast!operator new+0x1a:
00ac1ff3 e8293a0000 call testcast!malloc (00ac5a21)
……
0:000:x86> p
testcast!Globaltest+0x4e:
00ac10be 68d84eae00 push offset testcast!std::_Iosb<int>::end+0x4 (00ae4ed8)
0:000:x86> g
Breakpoint 1 hit
testcast!Globaltest:
00ac1070 55 push ebp
0:000:x86> g
(1a58.b40): C++ EH exception - code e06d7363 (first chance)
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:WindowsSYSTEM32wow64.dll -
ntdll!ZwTerminateProcess+0xa: 一直执行到进程退出
00000000`77b8f97a c3 ret
0:000> g
^ No runnable debuggees error in 'g'
调试过程截图