是否有用于确定帧指针未被消除的gcc宏?
当使用-fomit-frame-pointer(对于各种-O设置自动)时,执行回溯是有问题的。 我想知道是否有一种方法可以在编译时确定代码是用这个开关编译的? 在那种情况下,我可以放入一个#ifndef来防止在不明智的情况下进行反向追踪。
当此-fomit-frame-pointer开关打开时是否设置了任何宏?
谢谢,
那么setjmp
我刚试过这个:
gcc -E -fomit-frame-pointer -Wp,-dM foo.c> fpo.out gcc -E -Wp,-dM foo.c> no-fpo.out diff no-fpo.out fpo.out
其中foo.c是一个简单的“Hello World”程序,但没有得到任何结果。 这意味着所有预处理器宏都是相同的,无论是否使用了-fomit-frame-pointer
。 所以我认为你的问题的答案是“不”。
您可以做的最好的事情是在使用-fomit-frame-pointer
时修改Makefile(或构建过程使用的任何内容)来定义自己的宏(例如-DNO_FRAME_POINTERS
或其他东西)。
至于检查,在运行时检查ebp寄存器(针对您的架构进行调整)是否指向堆栈顶部下方的几个字节,然后如果跟随存储在[ebp]的指针有意义。
您无法在编译时执行此操作,但在运行时,您可以检查程序是否已优化。
编写一个肯定会被优化器更改的代码,比如将非易失性变量与setjmp
/ longjmp
,并通过该变量的值来了解您的程序是否已优化。
#include #include int is_optimised(void) { int i = 1; jmp_buf jmp_loc; if (setjmp(jmp_loc)) { return i; // optimiser changes it to "return 1" } i = 0; longjmp(jmp_loc, 1); return 0; } int main(int argc, char *argv[]) { printf("%soptimised\n", is_optimised() ? "" : "non-"); return 0; }
如果使用GCC编译而没有-O
开关,则打印“ non-optimised
”,对于开关-O1
到-O4
它打印“ optimised
”。
当然,您的里程(与其他编译器一起)可能会有所不同。