在 Windows 下获取指向调用堆栈底部的指针并按地址解析符号(如 dladdr)?

发布于 2024-09-25 05:19:16 字数 783 浏览 9 评论 0原文

我想在 Windows 下实现一个类似的 backtrace 实用程序,以便将此信息添加到异常中。

我需要捕获返回地址,然后将其转换为符号名称。

我知道 StackWalk64 和 StackWalker 项目,但不幸的是它有几个重要的缺点

  • :慢(StackWalk64),我不想浪费太多时间来收集跟踪,基本上可以像在链表上行走一样快地完成。
  • 已知函数 StackWalk64 不是线程安全的。

我只想支持 x86 和可能的 x86_64 架构

我的基本想法如下:

  1. 使用 esp/ebp 寄存器在堆栈上运行,类似于 GCC 的 __builtin_return_address(x)/__builtin_frame_address(x) doe 直到到达堆栈底部(这就是 glibc 所做的)。
  2. 将地址转换为符号
  3. 对它们进行分解。

问题/疑问:

  1. 我如何知道我到达了堆栈的顶部?例如,glibc 实现有 __libc_stack_end,因此很容易找到停止的位置。 Windows下有类似的东西吗?如何获取栈底地址?
  2. 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:

  1. 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).
  2. Translate addresses to symbols
  3. Demangle them.

Problems/Questions:

  1. 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?
  2. 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

盛装女皇 2024-10-02 05:19:16
  • 捕获堆栈跟踪:RtlCaptureStackBackTrace
  • 获取符号:使用 DBG 帮助库(仅限 MSVC)。主要功能:

    //初始化
    hProcess = GetCurrentProcess()
    SymSetOptions(SYMOPT_DEFERRED_LOADS)
    SymInitialize(hProcess,NULL,TRUE)
    // 获取符号
    SymFromAddr(...)
    

    可以找到实现那里

  • Capturing Stack Trace: RtlCaptureStackBackTrace
  • Getting Symbols: Using DBG Help library (MSVC only). Key functions:

    // Initialization
    hProcess = GetCurrentProcess()
    SymSetOptions(SYMOPT_DEFERRED_LOADS)
    SymInitialize(hProcess, NULL, TRUE)
    // Fetching symbol
    SymFromAddr(...)
    

    Implementation can be found there

薄荷→糖丶微凉 2024-10-02 05:19:16

您使用 StackWalk 但稍后解析符号。

You use StackWalk but resolve symbols later.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文