2009-09-12 65 views
2

当使用-fomit-frame-pointer(自动设置各种-O设置)时,执行回溯是有问题的。我想知道在编译时是否有一种方法确定代码是用这个开关编译的?在这种情况下,我可以放入#ifndef以防止在不明智的情况下回溯。是否有gcc宏来确定帧指针没有被消除?

这个-fomit-frame指针开关打开时是否设置了任何宏?

感谢,

的setjmp

回答

2

我只是尝试这样做:

 
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” 程序,并没有得到结果。这意味着所有的预处理器宏都是相同的,无论是否使用。所以我认为你的问题的答案是“不”。

也许你能做的最好的就是修改你的Makefile(或任何你的构建过程中使用)来定义你自己的宏观(例如-DNO_FRAME_POINTERS,或东西)使用时。

+1

优化意味着-fomit-frame-pointer,我猜这是主要问题。 – qrdl 2009-09-12 19:41:03

+0

根据gcc文档,优化并不总是意味着-fomit-frame-pointer。它可以依赖于架构,以及特定优化如何影响调试能力。从手册页:“-O也会在机器上打开-fomit-frame-pointer,这样做不会干扰调试。” – 2009-09-13 00:00:38

1

你不能在编译时做它,但在运行时你可以检查你的程序是否优化。

编写一个肯定会被优化器改变的代码,如混合非易失性变量与setjmp/longjmp,以及该变量的值,您将知道程序是否被优化。

#include <setjmp.h> 
#include <stdio.h> 

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”。

当然,您的里程(与其他编译器)可能会有所不同。

1

至于检查,在运行时检查ebp寄存器(调整您的体系结构)是否指向堆栈顶部以下的几个字节,然后如果遵循[ebp]中存储的指针是有意义的。