当使用-fomit-frame-pointer(自动设置各种-O设置)时,执行回溯是有问题的。我想知道在编译时是否有一种方法确定代码是用这个开关编译的?在这种情况下,我可以放入#ifndef以防止在不明智的情况下回溯。是否有gcc宏来确定帧指针没有被消除?
这个-fomit-frame指针开关打开时是否设置了任何宏?
感谢,
的setjmp
当使用-fomit-frame-pointer(自动设置各种-O设置)时,执行回溯是有问题的。我想知道在编译时是否有一种方法确定代码是用这个开关编译的?在这种情况下,我可以放入#ifndef以防止在不明智的情况下回溯。是否有gcc宏来确定帧指针没有被消除?
这个-fomit-frame指针开关打开时是否设置了任何宏?
感谢,
的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” 程序,并没有得到结果。这意味着所有的预处理器宏都是相同的,无论是否使用。所以我认为你的问题的答案是“不”。
也许你能做的最好的就是修改你的Makefile(或任何你的构建过程中使用)来定义你自己的宏观(例如-DNO_FRAME_POINTERS
,或东西)使用时。
你不能在编译时做它,但在运行时你可以检查你的程序是否优化。
编写一个肯定会被优化器改变的代码,如混合非易失性变量与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
”。
当然,您的里程(与其他编译器)可能会有所不同。
至于检查,在运行时检查ebp寄存器(调整您的体系结构)是否指向堆栈顶部以下的几个字节,然后如果遵循[ebp]中存储的指针是有意义的。
优化意味着-fomit-frame-pointer,我猜这是主要问题。 – qrdl 2009-09-12 19:41:03
根据gcc文档,优化并不总是意味着-fomit-frame-pointer。它可以依赖于架构,以及特定优化如何影响调试能力。从手册页:“-O也会在机器上打开-fomit-frame-pointer,这样做不会干扰调试。” – 2009-09-13 00:00:38