[cfe-dev] Unwind, exception handling, debuggers and profilers

Rafael EspĂ­ndola rafael.espindola at gmail.com
Wed Mar 19 19:09:02 PDT 2014


> ** Unwinding **
>
> AFAIK, there are three ways to unwind the stack:
>
> 1. Checking the return information on the stack (LR). This might be
> optimized away, so debuggers and profilers can't rely on it. Binaries
> with no debug or EH information at all have to resort to this when
> back-tracing during a segfault or similar.
>
> 2. Dwarf unwinding. This is a carefully constructed stack unwinding
> Dwarf information for each frame that debuggers and profilers can use
> to gather precise information on the stack, typically stored on
> .eh_frame sections.
>
> 3. Itanium-compatible exception handling. This is another format of
> unwind tables using personality routines and similar unwinding logic
> to Dwarf CFI directives, also on .eh_frame. This is why you can use
> CFI to build the EH tables, and why debuggers can also use this table
> to unwind the stack.

I think this is just 2. It uses .eh_frame for unwinding proper. The
only  difference in .eh_frame is that there is a personality function
defined.

> ** Exception Handling **
>
> LLVM has four types of EH: Dwarf, ARM, SjLj and Win64. Of them, only
> SjLj doesn't need unwind tables, and each of the others, even being
> Itanium-compatible, need slightly different logic.
>
> In LLVM, all targets that use DwarfCFIException are using the same
> tables as the debugger and profilers would, but ARM and Win64 have
> separate unwind logic. This is where the problem begins.
>
> We're left with three EH types:
>
> 1. No tables (SjLj)
> 2. Dwarf tables (DwarfCFI)
> 3. Specific EH tables (ARM, Win64?)
>
> ** Debug & Profiling **
>
> In debug/profile mode (-g, -pg), none of the optimizations that prune
> unwind information should be allowed to run.

No. The -g option should never change the set of optimizations that
are run. We can add a -Og that means only debug info friendly
optimizations, but it should be independent.

> A function without any of the attributes below should emit *no* tables at all.
>
> The remaining possibilities are:
>
> * uwtable
>   - Generated only when -g or -pg are specified

No. Se above note about -g.

>   - Option -fno-unwind-tables loses meaning (unless nounwind has meaning)
>   - Generate full EH/Debug tables on all archs
>
> * ehtable
>   - Generated for EH only (front-end/arch/lang specific)
>   - Could be forced enabled/disabled via -feh-tables/-fno-eh-tables
>   - Only emits EH directives on ARM, full debug on others, nothing on SjLj

So, I am not really familiar with how we do exception handling, so my
only opinion is about the X86-64 abi and LTOing files compiled with
and without -fno-asynchronous-unwind-tables.  Having a table entry is
mandated by the ABI, and  -fno-asynchronous-unwind-tables is a non abi
conformant
option for a user that really knows what it is doing.

What we do today then is that on x86-64 "clang -S" adds uwtable to all
functions and "clang -S -fno-asynchronous-unwind-tables" doesn't. The
net result is that we get tables for the same functions with and
without LTO. I would really like to keep this property and this simple
logic in the x86 backend.

>From previous discussions it seems that the idea was for other
backends to read it as "make it possible to unwind past this
function". It that is not too specific, we could add other attributes,
for example:

* frame-pointer. Added by the FE when building with -fno-omit-frame-pointer.
* arm-unwind-table. The other unwind table format.

Cheers,
Rafael



More information about the cfe-dev mailing list