例如,我想在 Windows 下实现一个类似的回溯实用程序,以便将此信息添加到异常中。
我需要捕获返回地址,然后将其转换为符号名称。
我知道 StackWalk64 和StackWalker 项目,但不幸的是它有几个重要的缺点:
- 众所周知它非常慢(StackWalk64),我不想浪费太多时间来收集跟踪,基本上可以像在链表上行走一样快。
- 已知函数 StackWalk64 不是线程安全的。
我只想支持 x86 和可能的 x86_64 架构
我的基本想法如下:
- 使用 esp/ebp 寄存器在堆栈上运行,类似于 GCC 的
__builtin_return_address(x)
/__builtin_frame_address(x)
doe 直到我到达堆栈底部(这就是 glibc 所做的)。 - 将地址转换为符号
- 拆解它们。
问题/疑问:
- 我怎么知道我到达了堆栈的终点?例如 glibc 实现有
__libc_stack_end
,所以很容易找到停止的地方。Windows下有类似的东西吗?如何获取栈底地址? - dladdr 功能的类似物是什么。现在我知道,与保留大部分符号名称的 ELF 平台不同,PE 格式没有。所以它应该以某种方式读取调试信息。有任何想法吗?