请查看位于Kernel32.dll中的CaptureStackBackTrace()函数,它可以捕获堆栈回溯信息。这个函数可以满足你的所有需求。
通过遍历堆栈并记录每个帧的信息,来捕获堆栈回溯信息。
USHORT WINAPI CaptureStackBackTrace(
__in ULONG FramesToSkip,
__in ULONG FramesToCapture,
__out PVOID *BackTrace,
__out_opt PULONG BackTraceHash
);
如果你想要进行这个极其不可移植的操作,你可以直接读取EBP寄存器并手动遍历栈。这种方法只适用于x86架构,并且假定你使用的C运行时在调用第一个函数之前正确地将EBP初始化为0。
uint32_t read_ebp(void)
{
uint32_t my_ebp;
__asm
{
mov ebp, my_ebp
}
return my_ebp;
}
void backtrace(void)
{
uint32_t ebp = read_ebp();
printf("backtrace:\n");
while(ebp != 0)
{
printf("0x%08x\n", ebp);
ebp = ((uint32_t *)ebp)[1];
}
}
之前的变体对我不起作用(msvc 6),所以:
unsigned long prev;
unsigned long addr;
__asm { mov prev, ebp }
while(addr!=0) {
addr = ((unsigned long *)prev)[1];
printf("0x%08x\n", addr);
prev = ((unsigned long *)prev)[0];
}
Adam, thanks for highlighting the way!