7

如何在不使用 dbghelp.dll 的情况下获取 Windows 上的地址堆栈跟踪?

我不需要知道与地址关联的符号或函数名称,我只需要地址列表——类似于*nix 系统的回溯

谢谢!

4

3 回答 3

9

查看 Kernel32.dll 中的CaptureStackBackTrace()函数。这应该可以满足您的所有需求。

通过向上走堆栈并记录每一帧的信息来捕获堆栈回溯。

USHORT WINAPI CaptureStackBackTrace(
  __in       ULONG FramesToSkip,
  __in       ULONG FramesToCapture,
  __out      PVOID *BackTrace,
  __out_opt  PULONG BackTraceHash
);
于 2008-12-24T23:42:07.797 回答
2

如果您想以极其不可移植的方式执行此操作,则可以只读取 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];
    }
}
于 2008-12-25T00:30:57.977 回答
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]; 
}
亚当,谢谢你强调的方式!

于 2009-03-19T17:54:51.977 回答