在这一系列之前的两篇文章中,我介绍了如何在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
如下图所示