Getting C++ exception handling to work

M66B

Mitglied
Mitglied seit
17 Feb 2010
Beiträge
225
Punkte für Reaktionen
0
Punkte
0
I am struggling to get s3fslite to work (see ticket #796). It compiles and runs, but as soon an exception occurs it aborts. Exceptions are part of the normal flow of this package, so this is a problem. I tried a lot of things, but cannot get exception handling to work. Has anybody an idea how to solve this?
 
Did you use uclibc++?
Maybe you should try to use glib2 (available in freetz-libraries) instead of uclibc++ for building your application.
 
Zuletzt bearbeitet:
Thanks for the tip, but the problem didn't go away :(.
Maybe other libraries depend on uClibc++, since ldd outputs:
Code:
libglib-2.0.so.0 => /usr/lib/freetz/libglib-2.0.so.0 (0x2aabe000)
libfuse.so.2 => /usr/lib/freetz/libfuse.so.2 (0x2ab7a000)
libcurl.so.4 => /usr/lib/freetz/libcurl.so.4 (0x2aba8000)
libxml2.so.2 => /usr/lib/freetz/libxml2.so.2 (0x2abfa000)
libcrypto.so.0.9.8 => /usr/lib/freetz/libcrypto.so.0.9.8 (0x2ad19000)
libsqlite3.so.0 => /usr/lib/freetz/libsqlite3.so.0 (0x2ae2e000)
libpthread.so.0 => /lib/libpthread.so.0 (0x2aecf000)
libssl.so.0.9.8 => /usr/lib/freetz/libssl.so.0.9.8 (0x2aef3000)
libdl.so.0 => /lib/libdl.so.0 (0x2af3f000)
libz.so.1 => /usr/lib/freetz/libz.so.1 (0x2af52000)
libuClibc++.so.0 => /usr/lib/freetz/libuClibc++.so.0 (0x2af75000)
libc.so.0 => /lib/libc.so.0 (0x2afaf000)
libgcc_s.so.1 => /lib/libgcc_s.so.1 (0x2b065000)
libpcre.so.0 => /usr/lib/freetz/libpcre.so.0 (0x2b083000)
libintl.so.8 => /usr/lib/freetz/libintl.so.8 (0x2b0c0000)
libm.so.0 => /lib/libm.so.0 (0x2b0d8000)
ld-uClibc.so.0 => /lib/ld-uClibc.so.0 (0x2aaa8000)
I have attached a new patch to the ticket, with the glib dependency.
 
That´s true. AFAIK uclibc++ wont support exceptions in the future since it would bloat it too much.
 
I was afraid of this, so I have rewritten a lot of code to not use exceptions. A patch is attached to the ticket.
 
uClibc++ _does_ support exceptions, it's however broken now... I am not sure whether it's uClibc++' or freetz' fault... I'll look into it as soon as I have some time...

glib2 is a (very good) c-library, it has nothing to do with the implementation of "Standard C++ Library" (see C++ Standard) provided by uClibc++, i.e. they are not interchangeable.
 
I would be gratefull if you looked into this. It will make cross-compiling C++ packages that use exceptions a lot easier in general. Now it is more like cross-patching.
 
I have investigated the issue a bit. It seems it's a uClibc++ fault as my test program linked against libstdc++ catches all exceptions as expected whereas the same program linked against uClibc++ terminates after throwing the very first exception.

uClibc++ however doesn't implement exception handling itself. It declares all required functions and copies/steals their implementations from libstdc++ by extracting required object files from libsupc++.a and libgcc_eh.a (see src/abi folder). So the implementation is actually exactly the same as that contained in libstdc++. I assume that uClibc++ doesn't initialize some internal structures or whatever and that's the reason it doesn't work. I however didn't manage yet to find out what exactly is going wrong.

gdb produces the following output:
Code:
GNU gdb 6.8
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "mipsel-linux-uclibc"...
(gdb) run
Starting program: /var/media/ftp/uStor01/excepttest
Starting exception testing
Throwing out of range
terminate called after throwing an instance of 'std::out_of_range'
  what():  This is text

Program received signal SIGABRT, Aborted.
0x2ab1c694 in kill () from /lib/libc.so.0
(gdb) bt
#0  0x2ab1c694 in kill () from /lib/libc.so.0
#1  0x2ab5f968 in abort () from /lib/libc.so.0
#2  0x2aaec6dc in __gnu_cxx::__verbose_terminate_handler () from ./libuClibc++.so.0
#3  0x2aaea0b4 in __cxxabiv1::__terminate () from ./libuClibc++.so.0
#4  0x2aaea118 in std::terminate () from ./libuClibc++.so.0
#5  0x2aaea2ec in __cxa_throw () from ./libuClibc++.so.0
#6  0x00400ed8 in main (argc=<value optimized out>, argv=<value optimized out>) at excepttest.c:13
(gdb)

I should probably compile gcc or at least libsupc++ and libgcc_eh with debug information enabled to get more information as reading gcc's source code alone doesn't bring me any further as all this unwind/exception stuff is absolutely new to me...

I already contacted the maintainer of uClibc++, let's see what he suggests.

For those of you who'd like to investigate the issue by themselves here is the link that might be interesting. Also take a look at the source code of gcc in particular at that located in libstdc++-v3/libsupc++.

p.s. I have already looked at openwrt and incorporated some patches from them but it still doesn't solve the issue.
 
Thanks for your effort, er13!
I understand that it could/should work, so that's hopeful.
Lets wait what the maintainer of uClibc++ says.
Do you know if exceptions work in openwrt?
 
Maybe a patch similar to this one is what is needed?
 
The attached patch solves the issue for me (tested on my 7170 only). Could someone please test it on an uClibc-0.9.28 based box, I lent mine at the moment. Thanks!
 

Anhänge

  • uClibcxx_exceptions_fix.patch.txt
    1.4 KB · Aufrufe: 15
Thanks again for your efforts, er13!

Unfortunately I cannot test with uClibc-0.9.28, but I will definitely test with s3fslite (as soon as the repositories are back online).
 
I tested with s3fslite with the exceptions in place and it seems to work!

If others want to try this: you have to do a 'make distclean' to rebuilt the toolchain.

I will publish a new patch for s3fslite as soon as the repositories are back online.
 
@er13
Can you please explain what the option "IMPORT_LIBGCC_EH" does?

Regards
Oliver
 
It causes some (not all) of the object files from gcc's libgcc_eh.a to be extracted and linked in libuClibc++.so - this is the way uClibc++ "implements" exception handling, it doesn't actually implement it itself, it "steals/borrows" object files with required symbols from gcc.

I actually didn't manage to find out what exactly goes wrong. Fact is all required symbols are already contained in libgcc_s.so, so linking them in libuClibc++.so is unnecessary as each dynamically linked binary gets libgcc_s.so linked in. It is also not necessary to put them in libuClibc++.a as each statically linked binary gets gcc_eh linked in (the uclibc-g++-wrapper-script contains -lgcc_eh).
 
Holen Sie sich 3CX - völlig kostenlos!
Verbinden Sie Ihr Team und Ihre Kunden Telefonie Livechat Videokonferenzen

Gehostet oder selbst-verwaltet. Für bis zu 10 Nutzer dauerhaft kostenlos. Keine Kreditkartendetails erforderlich. Ohne Risiko testen.

3CX
Für diese E-Mail-Adresse besteht bereits ein 3CX-Konto. Sie werden zum Kundenportal weitergeleitet, wo Sie sich anmelden oder Ihr Passwort zurücksetzen können, falls Sie dieses vergessen haben.