2

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

当这个 -fomit-frame-pointer 开关打开时,是否设置了任何宏?

谢谢,

SetJmp

4

3 回答 3

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

可能您能做的最好的事情就是修改您的 Makefile(或您的构建过程使用的任何内容)-DNO_FRAME_POINTERS使用-fomit-frame-pointer.

于 2009-09-12T18:47:20.503 回答
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;
}

-O如果在没有开关的情况下使用 GCC 编译,它会打印“ non-optimised”,切换-O1-O4它会打印“ optimised”。

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

于 2009-09-12T19:05:09.617 回答
1

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

于 2009-09-12T19:24:48.307 回答