如何获取相对于堆栈帧的自动(本地)变量的偏移量(__builtin_frame_address)

Geo*_*tis 2 c c++ gcc

使用gcc,我需要跟踪在各种例程中分配的一些特殊变量的存在作为局部变量.为了做到这一点,我想在编译时发出信号.所以我需要在编译时获得一个方法来获取相对于堆栈帧的自动变量(具有本地范围的变量)的偏移量(相对于x86体系结构中的rbp寄存器).

我已经能够得到如下:

(char*)&a - (char*)__builtin_frame_address(0)
Run Code Online (Sandbox Code Playgroud)

问题是gcc不够智能,并且只能为常量的加载生成大量指令.所以我想知道是否偶然有任何隐藏的宏或内置直接给我,因为这是更简单的解决方案.

Tim*_*Tim 5

使用gcc,我需要跟踪在各种例程中分配的一些特殊变量的存在作为局部变量

仅仅因为变量具有自动存储并不意味着它将存在于堆栈中.编译器可能只是将它放在寄存器中,具体取决于它的使用方式.

所以我需要在编译时获得一个方法来获取相对于堆栈帧的自动变量(具有本地范围的变量)的偏移量(相对于x86体系结构中的rbp寄存器).

这没有任何意义.堆栈帧在编译时不存在.如果编译器决定内联函数会发生什么?编译时堆栈帧在哪里?

我已经能够得到如下:

(char*)&a - (char*)__builtin_frame_address(0)
Run Code Online (Sandbox Code Playgroud)

这是一种方法,它处理编译器在堆栈框架周围移动的情况.

问题是gcc不够智能,并且只能为常量的加载生成大量指令.

那是因为它不是一个常数.堆栈帧不是 BSS.地址可能无法在链接时计算.同样,内联器完全打破了你对堆栈框架的偏见.您可能需要阅读的文档__builtin_return_address.


最简单的解决方案是Severin Pappadeux建议的解决方案:

void foo() {
    int base = 0;
    // do stuff
    float my_special_var = 42.0f;
    std::ptrdiff_t special_var_offset = reinterpret_cast<char*>(&base) - reinterpret_cast<char*>(&my_special_var);
    std::cout << special_var_offset << std::endl;
}
Run Code Online (Sandbox Code Playgroud)