[Barrelfish-users] C++ exception handling - why it doesn't work

Chothia Zaheer zchothia at student.ethz.ch
Thu Jan 31 15:42:53 CET 2013


Hello,

[Don't feel obliged to reply. I don't need C++ exceptions but want to document my findings.]

This discussion refers to the toolchain described on the wiki [1].
(Send me a mail if you want to play with this; I have updated patches and a
script to automate the process.)

We start with a minimal example:
  int main() {
    try { throw 1234; } catch (int e) { /* IGNORE*/ }
    return 0;
  }

(Note: this also applies to a C program which uses _Unwind_Backtrace.)

The unwind tables seem to be correctly generated and the linker retains them in
the binary:
  $ readelf -S try_catch
  <...>
    [ 3] .eh_frame         PROGBITS         00000000004a1a20  000a1a20
         0000000000018d60  0000000000000000   A       0     0     8

Barrelfish's ELF loader also loads the corresponding program headers:
  Loading segment: start=0x400000, size=1362904, flags=5
  Loading segment: start=0x54dbe0, size=184481, flags=6

The program crashes with the following callstack:
  0x0000000000485a8a: abort at {BARRELFISH}/lib/newlib/newlib/libc/sys/barrelfish/syscalls.c:45
  0x000000000040b83c: uw_init_context_1 at libgcc/unwind-dw2.c:1502 (discriminator 1)

At this point, the current return address is used to locate the corresponding
FDE (Frame Description Entry) in the unwind tables.  The problem is that libgcc
doesn't know where these are located.

Option 1: During program startup call __register_frame and pass a pointer to the
start of the .eh_frame section.  Modify linker script to provide this as a symbol
(see [2]).

Option 2: Pass the '--eh-frame-hdr' option to the linker, which places a header
for the .eh_frame sections in a separate program segment (PT_GNU_EH_FRAME).
The unwinder can locate this using dl_iterate_phdr or the functions in
<elf/elf.h>.

Complication: currently crtbegin from Barrelfish's tree is used, however this
would need to be built as part of the toolchain so that libgcc's symbols are
visible.

If you are curious about how exception handling works have a look at [3] which
gives some background and historical context on stack unwinding and also the
articles by Ian Lance Taylor which delve into the details of how everything fits
together [4].

Regards,

--Zaheer

References:
[1] http://wiki.barrelfish.org/CrossCompiler
[2] http://gcc.gnu.org/ml/gcc-help/2011-07/msg00112.html
[3] http://gnu.wildebeest.org/blog/mjw/2007/08/23/stack-unwinding/
[4] - GCC Exception Frames:  http://www.airs.com/blog/archives/166
    - .eh_frame: http://www.airs.com/blog/archives/460
    - .eh_frame_hdr: http://www.airs.com/blog/archives/462



More information about the Barrelfish-users mailing list