在 Windows 下获取指向调用堆栈底部的指针并按地址解析符号(如 dladdr)?
我想在 Windows 下实现一个类似的 backtrace 实用程序,以便将此信息添加到异常中。
我需要捕获返回地址,然后将其转换为符号名称。
我知道 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 格式不会。所以它应该以某种方式读取调试信息。有什么想法吗?
I want to implement an analog of backtrace utility under windows in order to add this information to exception for example.
I need to capture return addresses and then translate it into symbols names.
I'm aware of StackWalk64 and of StackWalker project but unfortunately it has several important drawbacks:
- It is known to be very slow (the StackWalk64) and I don't want to waste much time for collecting the trace the basically can be done as fast as walking on linked list.
- The function StackWalk64 is known to be not thread safe.
I want to support only x86 and possible x86_64 architectures
Basic idea I have is following:
- Run on stack using esp/ebp registers similarly to what GCC's
__builtin_return_address(x)
/__builtin_frame_address(x)
doe till I reach the bottom of the stack (this is what glibc does). - Translate addresses to symbols
- Demangle them.
Problems/Questions:
- How do I know that I reach the to of the stack? For example glibc implementation has
__libc_stack_end
so it is easy to find where to stop. Is there any analog of such thing under Windows? How can I get stack bottom address? - What are the analogs of dladdr functionality. Now I know that unlike ELF platform that keeps most of symbol names, PE format does not. So it should read somehow the debug information. Any ideas?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
获取符号:使用 DBG 帮助库(仅限 MSVC)。主要功能:
可以找到实现那里
Getting Symbols: Using DBG Help library (MSVC only). Key functions:
Implementation can be found there
您使用 StackWalk 但稍后解析符号。
You use
StackWalk
but resolve symbols later.