What exactly happens when compiling with -funwind-tables?
Asked Answered
E

1

29

From: https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html

-fexceptions: Enable exception handling. Generates extra code needed to propagate exceptions. For some targets, this implies GCC generates frame unwind information for all functions,

-funwind-tables Similar to -fexceptions, except that it just generates any needed static data, but does not affect the generated code in any other way. You normally do not need to enable this option; instead, a language processor that needs this handling enables it on your behalf.

Could somebody please explain, from -funwind-tables, what does it mean by "any needed static data". What data they are referring to. And why is the data needed to be generated? What happens if that data is not generated? Where is that data used for?

And it also says "similar to -fexception". So I think it also generates frame unwind information. What is frame unwind information? Who uses the frame information and how?

In some SO posts, I read that programs has to be compiled with this flag for the _Unwind_Backtrace has to work properly. Please explain how _Unwind_Backtrace use the information generated by -funwind-tables.

Essequibo answered 1/11, 2018 at 13:22 Comment(3)
You might like this video about exceptions. It for MSVC ,but it gives you some insights. GCC probably takes similar techniques. youtube.com/watch?v=COEv2kq_Ht8Bozcaada
This may give you a start: itanium-cxx-abi.github.io/cxx-abi/exceptions.pdfCharlton
@engf-010, thank you, this link really provides much insights into the topic. suggest everybody who have questions like me to listen to it. naives like me, need to watch couple of times :)Essequibo
C
26

The static data mentioned for the -funwind-tables option is the frame unwind information, i.e. data that allows a running program to walk back the function call stack from a given execution point. Walking back the function call stack means moving from the execution context of a called function to the context of the caller, i.e. what normally happens when you return from a function, except that frame unwind information allows you to do that from an arbitrary point inside the body of a function; also you are not forced to actually exit the called function, you could simply "peek" inside the caller context (e.g. to retrieve the location from which the called function has been called), also recursively, but then continue the normal execution flow in the called function.

To be able to do the above you need to have access to more information on the compiled code than what is strictly needed for a program to follow a "normal" execution flow. This information (i.e. the frame unwind information) is put by the linker in special linker sections (e.g. the .eh_frame section for the x86 platform, or the .ARM.exidx and .ARM.extab sections for the ARM platform) dedicated for that purpose; these linker sections are the same that are needed in languages such as C++ to implement exception handling, where the execution flow could jump from a called function to its caller as a result of an exception being thrown. If you disable generation of this data by using the -fno-unwind-tables option, you won't be able to walk back the function call stack or use C++ exceptions.

Notably, frame unwind information is used by libunwind, a cross-platform library that supports generating backtraces, jumping to arbitrary points in the call stack, and more.

_Unwind_Backtrace() is a function implemented in the GCC core libraries (more specifically in libgcc_s) that allows executing a callback function (supplied as argument) for each frame in the call stack, i.e. starting from the context of the caller function, the moving to its caller, and so on. See https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/baselib--unwind-backtrace.html. Again, this function to be able to do its stuff needs to access the frame unwind information from the appropriate linker sections.

Chungchungking answered 2/11, 2018 at 9:46 Comment(3)
Thanks Francessco for the information. Is there any way to check if unwind information is present in .eh_frame(x86) or ARM.exidx and ARM.extab(arm) sections. Is there any particular string that confirms that such unwind information is actually present?Essequibo
I don't know much about the data format used in those linker sections, but for the ARM platform you can use the readelf utility with the -u command line option to display the unwind tables: if a file has been built with unwind information, readelf will display this info for each function in the code. The -u option doesn't support frame unwind info for x86, though.Chungchungking
Thanks for the fantastic answer!Bartonbartosch

© 2022 - 2024 — McMap. All rights reserved.