Add -funwind-tables
when cross-compiling, you can successfully unwind backtrace through the interface(_Unwind_Backtrace and _Unwind_VRS_Get
) in the libgcc library.
But when I added the -O2 option at cross-compiling time, unwind backtrace would fail. I pass -Q -O2 --help=optimizers
print out the optimization and testing, but the results and -O2 is different, very strange,

- 1
-
Did you look and see what `-O2` actually does? What the entire set of optimization options it enables? And what those options do? – Andrew Henle Dec 26 '19 at 10:20
-
I use `-Q -O2 -help=optimizers` lists the O2 optimized option,unwind related programming optimization have been tested, the strange thing is not found abnormal optimization options – W_xy Dec 26 '19 at 11:41
1 Answers
You haven't told us which ARM architecture you are building for - but assuming it's a 32-bit architecture, enabling -O2
has also enabled -fomit-frame-pointer
(§ -fomit-frame-pointer
)
The frame-pointer
The frame pointer contains the base of the current function's stack frame (and with the knowledge that the caller's frame pointer is stored on the stack, a linked list of all stack frames in the call-tree). It's usually described as fp
in documentation - a synonym for r11
.
Omitting the frame-pointer
The ARM register file is small at 16 registers - one of which is the program counter. The frame pointer is one of the 15 that remains and is used only for debugging and diagnostics - specifically to provide stack walk-backs and symbolic debugging.
-fomit-frame-pointer
tells the compiler to not maintain a frame pointer, thus liberating the r11
for other uses, and potentially avoiding spill of variables to the stack from registers. It also saves 4 bytes per stack-frame of stack storage and a store and load to the stack.
Naturally, if fp
is used as general purpose register, its contents are undefined and walk-backs won't work.
You probably want to reenable the frame pointer with -fno-omit-frame-pointer
for your own sanity.

- 9,029
- 4
- 30
- 46
-
The device is a 32bit armv7 architecture, and when I cross-compiled I chose the `-fomit-frame-pointer` and `-funwind-tables` options, and although there was no stack frame, the stack backtrace was OK. When I added `-O2` and `-funwind-tables`, I could no longer do stack backtracking, which I didn't think was relevant. I have checked relevant information, the unwind way stack backtrace of ARM architecture is mainly carried out through`.ARM.exidx` section, I suspect that `-O2` option has affected `.ARM.exidx` section, – W_xy Dec 27 '19 at 01:16
-
unwind-tables are used for C++ exception handling. In `-O0` the compiler isn't trying very hard or at all?) to avoid spilling registers - so `r11` is unlikely to get used as a general purpose register and will at least contain something - even it's a calling function's frame-pointer. – marko Dec 28 '19 at 16:48
-
-
I think O2 may have optimized some registers, causing the stack backtrace to fail,but I can't find the relevant optimization options – W_xy Dec 31 '19 at 10:50
-
Many optimisations have the potential to make temporary variables in programs invisible to the debugger - possibly because they are never computed at all - or are computed as part of a bigger operation or as a side-effect. I just did an experiment with CompilerExplorer - https://godbolt.org/z/wJbRpk - I tried to build a function which would result in use of the frame pointer - it was surprisingly difficult. `-fomit-frame-pointer` definitely inhibited it being written to the stack-frame. – marko Dec 31 '19 at 11:56
-
In addition to the above methods, do you know any other methods of process stack tracing? – W_xy Jan 13 '20 at 08:45