本文介绍windbg动态调试过程中一个非常有用的命令,wt的用法。

wt命令

wt命令之所以称为wt是因为它是watch and trace的简称,即用来观察和跟踪的命令。这个命令一般用在动态调试而不是dump分析中。他的作用是跟踪程序的执行过程,并将每个执行的调用打印到输出。

我们先准备一个简单的斐波那契计算代码,然后通过wt命令来追踪这个程序的执行。

#include "tchar.h"
#include <iostream> using namespace std; unsigned Fibonacci(unsigned n)
{
if(n <= )
{
return n;
}
return Fibonacci(n-) + Fibonacci(n-);
} int _tmain(int argc, _TCHAR* argv[])
{
cout << Fibonacci() << endl;
return ;
}

将以上代码编译之后通过windbg打开运行,然后通过x命令查找入口函数main的地址,

0:000> x fibo!main
00391a40          fibo!main (int, char **)

通过uf命令反编译该函数,找出递归开始和结束的地址,

0:000> uf 00391a40          
fibo!main [c:\users\aaronzh\desktop\fibo.cpp @ 16]:
   16 00391a40 55              push    ebp
   16 00391a41 8bec            mov     ebp,esp
   17 00391a43 684c143900      push    offset fibo!ILT+1095(?endlstdYAAAV?$basic_ostreamDU?$char_traitsDstd (0039144c)
   17 00391a48 6a0a            push    0Ah
   17 00391a4a e8acfaffff      call    fibo!ILT+1270(?FibonacciYAIIZ) (003914fb)
   17 00391a4f 83c404          add     esp,4
   17 00391a52 50              push    eax
   17 00391a53 b9f0ad4000      mov     ecx,offset fibo!std::cout (0040adf0)
   17 00391a58 e870f6ffff      call    fibo!ILT+200(??6?$basic_ostreamDU?$char_traitsDstdstdQAEAAV01IZ) (003910cd)
   17 00391a5d 8bc8            mov     ecx,eax
   17 00391a5f e895f7ffff      call    fibo!ILT+500(??6?$basic_ostreamDU?$char_traitsDstdstdQAEAAV01P6AAAV01AAV01ZZ) (003911f9)
   18 00391a64 33c0            xor     eax,eax
   19 00391a66 5d              pop     ebp
   19 00391a67 c3              ret

通过wt命令来查看整个的递归调用过程,=后面是起始地址。

0:000> wt =00391a48 00391a4f
2 0 [] fibo!main
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
9 0 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
9 0 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
9 0 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
9 0 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
9 0 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
9 0 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
9 0 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
9 0 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
9 0 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
10 0 [] fibo!Fibonacci
15 11 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
10 0 [] fibo!Fibonacci
20 22 [] fibo!Fibonacci
15 43 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
10 0 [] fibo!Fibonacci
20 54 [] fibo!Fibonacci
15 75 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
9 0 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
10 0 [] fibo!Fibonacci
15 11 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
10 0 [] fibo!Fibonacci
20 22 [] fibo!Fibonacci
20 118 [] fibo!Fibonacci
15 139 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
9 0 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
9 0 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
10 0 [] fibo!Fibonacci
15 11 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
10 0 [] fibo!Fibonacci
20 22 [] fibo!Fibonacci
15 43 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
10 0 [] fibo!Fibonacci
20 54 [] fibo!Fibonacci
20 214 [] fibo!Fibonacci
15 235 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
9 0 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
9 0 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
9 0 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
10 0 [] fibo!Fibonacci
15 11 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
10 0 [] fibo!Fibonacci
20 22 [] fibo!Fibonacci
15 43 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
10 0 [] fibo!Fibonacci
20 54 [] fibo!Fibonacci
15 75 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
9 0 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
10 0 [] fibo!Fibonacci
15 11 [] fibo!Fibonacci
1 0 [] fibo!ILT+1270(?FibonacciYAIIZ)
10 0 [] fibo!Fibonacci
20 22 [] fibo!Fibonacci
20 118 [] fibo!Fibonacci
20 374 [] fibo!Fibonacci
....
....省略部分输出
....
2829 instructions were executed in 2828 events (0 from other threads) Function Name Invocations MinInst MaxInst AvgInst
fibo!Fibonacci 177 10 20 14
fibo!ILT+1270(?FibonacciYAIIZ) 177 1 1 1
fibo!main 1 2 2 2 0 system calls were executed eax=00000037 ebx=00000003 ecx=00000000 edx=00000000 esi=00000000 edi=003900d8
eip=00391a4f esp=0055f838 ebp=0055f868 iopl=0 nv up ei pl nz na po nc
cs=0023 ss=002b ds=002b es=002b fs=0053 gs=002b efl=00000202
fibo!main+0xf:
00391a4f 83c404 add esp,4

这个命令对于并不熟悉代码的调用过程的时候非常有用,通过这个方法调用跟踪,对于整个过程的方法调用过程就有了一个完整的概念,之后我们就可以根据相应的函数调用来设置相应的断点来查看我们关心的逻辑。
另外wt命令本身支持很多选项,常用的如下,

  • -l,指定要追踪的调用深度(注意后面的数字默认16进制)
  • -m,指定要追踪的特定模块,其他的模块调用会被忽略
  • -i,指定要被忽略的模块
  • -oR,显示函数调用返回值,这个选项对于你已知某个函数调用返回值的含义(例如access denied)时非常有用,通过这个选项追踪特定函数调用,然后直接全局搜索输出,来查看特定值是否被输出,结果就一目了然了。

希望以上内容对您有所帮助

Aaron Zhang

基础调试命令 - wt (watch and trace)的更多相关文章

  1. 基础调试命令 - .dump/.dumpcap/.writemem/!runaway

    Windbg是windows平台上强大的调试器,它相对于其他常见的IDE集成的调试器有几个重要的优势, Windbg可以做内核态调试 Windbg可以脱离源代码进行调试 Windbg可以用来分析dum ...

  2. 基础调试命令 - u/ub/uf

    在调试过程中难免会遇到需要反编译代码来分析逻辑的时候,在windbg中,需要反编译代码就要用到u/ub/uf这三个命令.本文这里分别介绍这三个命令各自的用途. 以下是一个quick sort的实例代码 ...

  3. gdb常用的调试命令

    首先将源代码编译.链接生成debug版本的可执行文件,然后通过‘gdb  debug版本的可执行文件名’进入调试模式. a) 单进程.单线程基础调试命令 l    显示main函数所在的文件的源代码 ...

  4. WinDBG 调试命令大全

    转载收藏于:http://www.cnblogs.com/kekec/archive/2012/12/02/2798020.html  #调试命令窗口 ++++++++++++++++++++++++ ...

  5. WinDbg调试命令汇总

    一. 1. !address eax 查看对应内存页的属性 2. vertarget 显示当前进程的大致信息 3 !peb 显示process Environment Block 4. lmvm 可以 ...

  6. Windbg调试命令详解

    作者:张佩][原文:http://www.yiiyee.cn/Blog] 1. 概述 用户成功安装微软Windows调试工具集后,能够在安装目录下发现四个调试器程序,分别是:cdb.exe.ntsd. ...

  7. python基础——调试

    python基础——调试 程序能一次写完并正常运行的概率很小,基本不超过1%.总会有各种各样的bug需要修正.有的bug很简单,看看错误信息就知道,有的bug很复杂,我们需要知道出错时,哪些变量的值是 ...

  8. Swift 使用 LLDB 调试命令

    swift 和 oc 的语法不一样: Xcode 调试技巧之 Swift 篇 打印和赋值,观察数值变量和view对象属性 p指令可打印其对象类型.内存地址以及该对象的值等具体信息, po指令则是打印其 ...

  9. gdb各种调试命令和技巧

    陈皓:用GDB调试程序 GDB概述———— GDB是GNU开源组织发布的一个强大的UNIX下的程序调试工具.或许,各位比较喜欢那种图形界面方式的,像VC.BCB等IDE的调试,但如果你是在UNIX平台 ...

随机推荐

  1. modesim测试语句

    : 'd2; Reg2 <= Reg1; i <= i + 1'b1; join : 'd2; i <= i + 1'b1; join : 'd2; Reg2 <= Reg1; ...

  2. C#方法中三个重要的参数:out、ref、params

    备注:适用于初学者,自学于传智播客. 1.out参数. 概念:如果在一个方法中,返回多个相同类型值的时候,可以考虑返回一数组.但是返回多个不同类型值的时候,返回数组显然不能解决问题,这时就引入out参 ...

  3. C# 获取屏幕的大小

    原文地址:http://www.cnblogs.com/zp89850/archive/2011/08/23/2151052.html C# 获取屏幕的大小 WinForm: int iActulaW ...

  4. javascript父级鼠标移入移出事件中的子集影响父级的处理方法

    一.我们先分析其产生的原因: 1.当鼠标从父级移入子集时触发了父级的两个事件:a.父级的mouseout事件(父级离开到子集):b.由于事件冒泡影响,又触发了父级的mouseover事件(父级移入父级 ...

  5. 如何更改OS系统下截图生成图片格式 jpg pdf

    Mac系统下快速截屏的快捷键: 1.截全屏: shift + command + 3 2.选取截屏 shift + command + 4 生成的图片,系统默认格式忘了,反正不好用,用下面命令更改生成 ...

  6. Fiddler 手机端证书安装No root certificate was found

    测试过程中发现在浏览器中访问代理服务器及端口,不通,提示要安装证书. 点击证书安装时,提示错误: No root certificate was found,Have you enabled HTTP ...

  7. AOP实现原理

    Spring 为解耦而生,其中AOP(面向切面编程)是很浓重的一笔. 本文来探讨一下AOP实现的原理. 一. 概述 代理模式是常用的java设计模式,他的特征是代理类与委托类有同样的接口,代理类主要负 ...

  8. 【九度OJ】题目1054:字符串内排序

    题目描述: 输入一个字符串,长度小于等于200,然后将输出按字符顺序升序排序后的字符串. 输入: 测试数据有多组,输入字符串. 输出: 对于每组输入,输出处理后的结果. 样例输入: bacd 样例输出 ...

  9. jQuery in action 3rd - Working with properties, attributes, and data

    properties properties 是 JavaScript 对象内在的属性,可以进行动态创建,修改等操作. attributes 指的是 DOM 元素标记出来的属性,不是实例对象的属性. 例 ...

  10. ruby 学习笔记 2 -变量

    变量 在ruby的世界里,变量有5种,全局变量 局部变量 实例变量 常量 类变量以及伪变量 常用的: 全局: 在全局使用,使用$开头,因为是全局的,所以在任何的代码例子中都可以改变其值,造成混乱,所以 ...