So what's the deal with debug_frame V eh_frame

While comparing debug info between GCC and Clang I found a section
that only Clang produces and GCC never produces: debug_frame.

It seems (though I haven't verified this with absolute certainty) as
though GCC just always uses eh_frame. LLVM on the other hand sometimes
uses eh_frame and sometimes uses debug_frame.

Here's an example:

int f1();
int i = f1();
void func() { }

Compiled with -fno-exceptions -g.

The first two lines produce a global ctor.

Clang is generous enough to flag the LLVM IR function for this global
ctor ("__cxx_global_var_init") as nounwind
(tools/clang/lib/CodeGen/CGDeclCXX.cpp:246), though "func" gets
flagged as nounwind but also as uwtable (why? I don't really
understand these semantics & haven't tracked down where that attribute
gets applied)

Without 'func' in this translation unit, LLVM emits a debug_frame
section (because no functions actually need an unwind table, but we're
compiling with debug info (without debug info LLVM emits no _frame
section at all)). With 'func', LLVM switches to emitting an eh_frame
section in both (-g and no -g) cases.

GCC on the other hand emits eh_frame in all 4 cases (with and without
-g and with and without 'func' defined).

Do we need all this logic? Should we just always use eh_frame? Should
we not have the 'uwtable' attribute on 'func'? Why is 'func' different
from the global ctor in this regard?

Confused,
- David

The advantage of using .debug_frame is that it can be easily stripped.
As the name implies, it is supposed to not change the semantic of code.
.eh_frame is used if the ABI for the current platform and language
settings requires unwinding support. If that is not the case, e.g. for
Linux/i386 compiling C (no special options) or C++ (-fno-exceptions),
the unwind support is optional and can be stripped. For NetBSD, we now
enable unwind support per default even for C, so it would always create
.eh_frame.

Joerg

While comparing debug info between GCC and Clang I found a section
that only Clang produces and GCC never produces: debug_frame.

It seems (though I haven't verified this with absolute certainty) as
though GCC just always uses eh_frame. LLVM on the other hand sometimes
uses eh_frame and sometimes uses debug_frame.

Here's an example:

int f1();
int i = f1();
void func() { }

Compiled with -fno-exceptions -g.

The first two lines produce a global ctor.

Clang is generous enough to flag the LLVM IR function for this global
ctor ("__cxx_global_var_init") as nounwind
(tools/clang/lib/CodeGen/CGDeclCXX.cpp:246), though "func" gets
flagged as nounwind but also as uwtable (why? I don't really
understand these semantics & haven't tracked down where that attribute
gets applied)

Is this x86-64? If so, uwtable is a abi requirement. It says that that
function should have an entry in .eh_table.

Without 'func' in this translation unit, LLVM emits a debug_frame
section (because no functions actually need an unwind table, but we're
compiling with debug info (without debug info LLVM emits no _frame
section at all)). With 'func', LLVM switches to emitting an eh_frame
section in both (-g and no -g) cases.

GCC on the other hand emits eh_frame in all 4 cases (with and without
-g and with and without 'func' defined).

Do we need all this logic? Should we just always use eh_frame? Should
we not have the 'uwtable' attribute on 'func'? Why is 'func' different
from the global ctor in this regard?

.debug_frame is a non-load section. It is therefore an optimization to
emit it instead of .eh_frame. It is very likely not really a relevant
one, so it might be possible to just always use .eh_frame.

Not adding uwtable for _GLOBAL__I_a might actually be a bug. I will
check what gcc does.

Cheers,
Rafael

While comparing debug info between GCC and Clang I found a section
that only Clang produces and GCC never produces: debug_frame.

It seems (though I haven't verified this with absolute certainty) as
though GCC just always uses eh_frame. LLVM on the other hand sometimes
uses eh_frame and sometimes uses debug_frame.

Here's an example:

int f1();
int i = f1();
void func() { }

Compiled with -fno-exceptions -g.

The first two lines produce a global ctor.

Clang is generous enough to flag the LLVM IR function for this global
ctor ("__cxx_global_var_init") as nounwind
(tools/clang/lib/CodeGen/CGDeclCXX.cpp:246), though "func" gets
flagged as nounwind but also as uwtable (why? I don't really
understand these semantics & haven't tracked down where that attribute
gets applied)

Is this x86-64? If so, uwtable is a abi requirement. It says that that
function should have an entry in .eh_table.

Hmm, OK then - because I've certainly seen LLVM emit object files with
no eh_frame (as in the above example, if "func" is omitted).

Without 'func' in this translation unit, LLVM emits a debug_frame
section (because no functions actually need an unwind table, but we're
compiling with debug info (without debug info LLVM emits no _frame
section at all)). With 'func', LLVM switches to emitting an eh_frame
section in both (-g and no -g) cases.

GCC on the other hand emits eh_frame in all 4 cases (with and without
-g and with and without 'func' defined).

Do we need all this logic? Should we just always use eh_frame? Should
we not have the 'uwtable' attribute on 'func'? Why is 'func' different
from the global ctor in this regard?

.debug_frame is a non-load section. It is therefore an optimization to
emit it instead of .eh_frame. It is very likely not really a relevant
one, so it might be possible to just always use .eh_frame.

Not adding uwtable for _GLOBAL__I_a might actually be a bug. I will
check what gcc does.

In my experiments GCC /always/ produced eh_frame, never debug_frame, fwiw.

Hmm, OK then - because I've certainly seen LLVM emit object files with
no eh_frame (as in the above example, if "func" is omitted).

I just reported pr19213 with your testcase. Thanks!

Not adding uwtable for _GLOBAL__I_a might actually be a bug. I will
check what gcc does.

In my experiments GCC /always/ produced eh_frame, never debug_frame, fwiw.

We could definitely experiment with that.

Cheers,
Rafael

Hmm, OK then - because I've certainly seen LLVM emit object files with
no eh_frame (as in the above example, if "func" is omitted).

I just reported pr19213 with your testcase. Thanks!

Awesome - I've added some more details there.