Why GCC compiled C program needs .eh_frame section?
Solution 1:
First of all, the original reason for this was largely political - the people who added DWARF-based unwinding (.eh_frame
) wanted it to be a feature that's always there so it could be used for implementing all kinds of stuff other than just C++ exceptions, including:
backtrace()
__attribute__((__cleanup__(f)))
-
__builtin_return_address(n)
, forn>0
-
pthread_cleanup_push
, implemented in terms of__attribute__((__cleanup__(f)))
- ...
However if you don't need any of these things, .eh_frame
is something like a 15-30% increase to .text
size with no benefit. You can disable generation of .eh_frame
with -fno-asynchronous-unwind-tables
for individual translation units, and this mostly eliminates the size cost, although you still have a few left over coming from crtbegin.o
, etc. You cannot strip them with the strip
command later; since .eh_frame
is a section that lives in the loaded part of the program (this is the whole point), stripping it modifies the binary in ways that break it at runtime. See https://sourceware.org/bugzilla/show_bug.cgi?id=14037 for an example of how things can break.
Note that DWARF tables are also used for debugging, but for this purpose they do not need to be in the loadable part of the program. Using -fno-asynchronous-unwind-tables
will not break debugging, because as long as -g
is also passed to the compiler, the tables still get generated; they just get stored in a separate, non-loadable, strippable section of the binary, .debug_frame
.