问题
When -fomit-frame-pointer is used (automatic for various -O settings), performing a backtrace is problematic. I am wondering if there is a way of determining at compile time that the code is compiled with this switch? In that case, I could put in an #ifndef to guard against backtracing when ill-advised.
Is any macro set when this -fomit-frame-pointer switch is on?
Thanks,
SetJmp
回答1:
I just tried this:
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
where foo.c is a simple "Hello World" program, and got no results. This means all of the preprocessor macros were identical, whether -fomit-frame-pointer
was used or not. So I think the answer to your question is "no".
Probably the best you can do is modify your Makefile (or whatever your build process uses) to define your own macro (e.g. -DNO_FRAME_POINTERS
, or something) when using -fomit-frame-pointer
.
回答2:
As for the check, at runtime check if ebp register (adjust for your architecture) points to a few bytes below the top of the stack and then if following the pointer stored at [ebp] makes sense.
回答3:
You cannot do it at compile time, but at runtime you can check whether your program optimised or not.
Write a code that definitely will be changes by optimiser, like mixing non-volatile variable with setjmp
/longjmp
, and by the value of that variable you will know whether your program is optimised or not.
#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;
}
If compiled with GCC without -O
switch it prints "non-optimised
", for switches -O1
to -O4
it prints "optimised
".
Of course your mileage (with other compilers) may vary.
来源:https://stackoverflow.com/questions/1415414/is-there-a-gcc-macro-for-determining-that-frame-pointers-are-not-eliminated