【问题标题】:Stack/Frame pointer as external variable堆栈/帧指针作为外部变量
【发布时间】:2018-09-15 18:23:03
【问题描述】:

目前,我正在编写一些日志记录逻辑,并想做一些缩进。了解是否存在任何函数调用或某个函数是否已完成的最简单方法是查看堆栈/帧的当前地址。假设堆栈倒置增长,那么如果log() 调用中的堆栈地址较小,那么在上一次调用期间我们可以增加缩进,因为存在一些函数调用。我知道有像backtrace() 这样的函数知道如何转储它,或者您可以使用一些程序集,但是,我记得读取可用于检索此信息的外部变量。有人可以命名这些变量或提供参考我在哪里可以找到它们(据我所知,它是在一些计算机系统书籍中,如“计算机系统:程序员的观点”)。否则,获取此信息最方便/快捷的方式是什么?

【问题讨论】:

  • 如果你想知道当前正在执行什么函数,我想你想查看当前的 RIP(程序计数器),而不是 RSP(堆栈指针)。 libm 中的log() 可能是一个叶子函数,所以它不会调用其他函数。还是您正在编写自己的函数,其名称与执行无关操作的数学库函数的名称相同?
  • 'log()' 只是我的宏/函数,它应该查看帧地址(在其中调用它)并将其与以前的地址进行比较,因此 RIP 对我没有兴趣
  • gcc下可以使用特殊功能:__builtin_return_address__builtin_frame_address等。详见gcc信息页面
  • 就像@R 所说的,这是一个高度专业化的领域。 GCC 提供 Backtrace API 来遍历堆栈。请参阅 GCC 手册中的 34.1 Backtraces。我不记得用于 MSVC 和 Windows 的类似 API。 John Robbin 的Debugging Applications 书可能有一些建议,但我手头没有。它可能是调试工具 SDK 的一部分。

标签: c++ c linux assembly


【解决方案1】:

这种方法是高度不可移植的,并且会在各种转换下中断,但如果您只是将它用于调试日志记录,它可能是合适的。

获取类似于当前堆栈帧地址的最简单方法是获取任何自动存储(本地、非静态)变量的地址。如果您想要一个基线来比较它,请将一些本地的地址保存在main 或类似于全局变量中。如果您的程序是或可能是多线程的,如果需要,请为此使用线程局部变量。

【讨论】:

  • 或者对于基线,传递const char*const void* 类型的额外函数arg。递归调用可以传递 arg 以使用相同的引用,但其他调用可以传递本地地址。不过,静态存储可能更有效,即使它必须是线程本地的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-12-26
  • 1970-01-01
  • 1970-01-01
  • 2020-01-03
  • 1970-01-01
  • 1970-01-01
  • 2019-03-07
相关资源
最近更新 更多