小览CallStack(调用栈)(三)-用调试器脚本查看调用栈信息

在这一系列之前的两篇文章中,我介绍了如何在windbg中查看调用栈的相关 信息(详见小览call stack(调用栈)(一)),以及调用约定(详见小览call stack(调用栈) (二)——调用约定)。今天的这篇博客在二者的基础 之上,介绍如何使用调式器脚本程序来观察调用栈。对CallStack感兴趣的朋友 可以在此基础上开发更加详尽的脚本来观察CallStack的信息;对调试感兴趣的 朋友则可以看一下DScript的用处。

我们先来看一个例子,下面的程序并不是一个优美的程序片段,但是它能够 帮助我们说明问题。程序使用了一个简单的递归,把1到参数d的和累加到sum之 上。在main中,我们把d设为10,这样,在断点处,我们就能获得一个深度为11 的调用栈。

#include <stdio.h>

int SumToOne(int d, int sum)
{
    sum += d;
    if (d != 1)
        sum = SumToOne(d-1, sum);
    else
        sum = sum; // 这条语句方便设置断点
    return sum;
}

void main()
{
    int sum = SumToOne(10, 0);
    printf("sum=%d", sum);
}

然后,在当前文件夹下,编辑调试器脚本文件DumpStack.txt,内容如下

.printf "Dump %d frames\n", ${$arg1}
r $t1=@ebp;
.for (r $t0=1; $t0<=${$arg1}; r $t0=$t0+1)
{
    .printf "frame %d, d=%d sum=%d\n", $t0, poi($t1+8), poi($t1+c)
    r $t1=poi($t1)
}

在windbg中,运行程序,当程序停止在断点处时,执行脚本

$$>a< “dumpStack.txt”a

如下图所示

时间: 2024-10-29 04:43:10

小览CallStack(调用栈)(三)-用调试器脚本查看调用栈信息的相关文章

第二章排错的工具:调试器Windbg(上)

感谢博主 http://book.51cto.com/art/200711/59731.htm <Windows用户态程序高效排错>第二章主要介绍用户态调试相关的知识和工具.本文主要讲了排错的工具调试器Windbg.     第二章 汇编.异常.内存.同步和调试器--重要的知识点和神兵利器 这一部分主要介绍用户态调试相关的知识和工具.包括汇编.异常exception.内存布局.堆heap.栈stack.CRTC Runtime.handle/Criticalsection/thread con

开发一个Linux调试器(二):断点

在该系列的第一部分,我们写了一个小的进程启动器,作为我们调试器的基础.在这篇博客中,我们会学习在 x86 Linux 上断点是如何工作的,以及如何给我们工具添加设置断点的能力. 系列文章索引 随着后面文章的发布,这些链接会逐渐生效. 准备环境 断点 寄存器和内存 Elves 和 dwarves 源码和信号 源码层逐步执行 源码层断点 调用栈 读取变量 10.之后步骤 断点是如何形成的? 有两种类型的断点:硬件和软件.硬件断点通常涉及到设置与体系结构相关的寄存器来为你产生断点,而软件断点则涉及到修

开发一个Linux调试器(十):高级主题

我们终于来到这个系列的最后一篇文章!这一次,我将对调试中的一些更高级的概念进行高层的概述:远程调试.共享库支持.表达式计算和多线程支持.这些想法实现起来比较复杂,所以我不会详细说明如何做,但是如果你有问题的话,我很乐意回答有关这些概念的问题. 系列索引 准备环境 断点 寄存器和内存 ELF 和 DWARF 源码和信号 源码级逐步执行 源码级断点 堆栈展开 处理变量 高级话题 远程调试 远程调试对于嵌入式系统或对不同环境进行调试非常有用.它还在高级调试器操作和与操作系统和硬件的交互之间设置了一个很

小览call stack(调用栈) (一)

栈在计算机领域中是个经常提到的名词,数据结构中有栈:网络传输中有协 议栈.今天我们讨论的调用栈(call stack),指的是在程序的执行过程中存储函 数调用信息的动态数据结构. 这个定义可能太抽象了一些,在给出具体的例子之前,请大家先思考一个问 题,哪些信息是函数调用过程中所需要的?或者这么问,一个编译器,在面对一 个函数的调用指令时,该生成哪些代码? 首先,函数的返回地址要保存下来.就好像你和你的小狗玩仍飞碟游戏,每 一个函数调用好比扔一个飞碟,当你的狗狗哼兹哼兹的捡来飞碟,函数完执行的 时

虚函数与多态小览

一.文章来由 Bill又写文章来由了哇~~早就想好好搞清这个问题了,这是c++领域里面比较难搞定的一块知识点,而且最近在看设计模式,里面有涉及这块,之前学过的不用容易玩忘记,于是就干脆研究透一点,也好碰到.用到的时候不心慌~于是有了这篇文章. 二.从编译时和运行时说起 2.1 编译时: 顾名思义就是正在编译的时候.就是编译器帮你把源代码翻译成机器能识别的代码.(当然只是一般意义上这么说,实际上可能只是翻译成某个中间状态的语言.比如Java只有JVM识别的字节码,C#中只有CLR能识别的MSIL)

C++抽象类小览

一.文章来由 virtual 方法和 virtual 类可以说是c++语言的一大特性,甚至有人说是c++语言的精髓,其实这么说也是有一定道理的,因为运行时多态在c++中体现淋漓尽致,而 virtual 就是为多态服务的.这也是一个一定要搞懂的c++问题,所以有了这篇文章.同时,我觉得这类底层问题不可能一文以蔽之,而且我也相信真正想搞懂这个问题的读者,不会只读我这一篇文章,所以只是小览,同时欢迎讨论和指正. 二.引入原因 其实,引入纯虚函数的原因我在我另一篇文章虚函数与多态小览就有写,不过重要的话

工厂模式与抽象工厂模式小览(二)

一.文章来由 就等啦~~还记得工厂模式与抽象工厂模式小览(一)第一部吗?我们在第一部中,分别详细的描述了(1)简单工厂(2)工厂模式(3)抽象工厂模式,但是并没有描述他们之间的关系,也没有比较工厂模式和抽象工厂模式,这对难舍难分的好基友之间的异同点,这些工作我们在第二部中完成~ 二.工厂模式和简单工厂 话说十年前,有一个暴发户,他家有三辆汽车--Benz奔驰.Bmw宝马.Audi奥迪,还雇了司机为他开车.不过,暴发户坐车时总是怪怪的:上Benz车后跟司机说"开奔驰车!",坐上Bmw后他

sizeof小览

一.文章来由-一道面试题迁出的探究 我发现我已经形成一种习惯写来由了,以后看博客的时候可以让我回忆起为什么出现这个问题,我用什么方法解决的,既然形成习惯就让这个习惯保持下去吧.今天实验室师姐在看书,一处不解,是关于sizeof的,大家讨论此问题后,我一向信服做了才知道答案,于是有了这篇文章.但是只能叫小览,因为不可能总结完sizeof的用法,欢迎补充和讨论. 二.从这道题目说起 我直接将问题的关键部分提出来: string strArr1[] = { "Trend", "Mi

开发一个Linux调试器(三):寄存器和内存

上一篇博文中我们给调试器添加了一个简单的地址断点.这次,我们将添加读写寄存器和内存的功能,这将使我们能够使用我们的程序计数器.观察状态和改变程序的行为. 系列文章索引 随着后面文章的发布,这些链接会逐渐生效. 准备环境 断点 寄存器和内存 Elves 和 dwarves 源码和信号 源码级逐步执行 源码级断点 调用栈展开 读取变量 下一步 注册我们的寄存器 在我们真正读取任何寄存器之前,我们需要告诉调试器一些关于我们的目标平台的信息,这里是 x8664 平台.除了多组通用和专用目的寄存器,x86