I'm using a toolchain with glibc and the following simple program crashes: #include <cstdio> int main() { try { throw 42; } catch (int x) { printf("catch %d\n", x); } } with the following backtrace: #0 0xb7747a92 in ?? () from /lib/ld-linux.so.2 #1 0xb74ac6b8 in raise () from /lib/libc.so.6 #2 0xb74adbae in abort () from /lib/libc.so.6 #3 0xb763903a in ?? () from /lib/libgcc_s.so.1 #4 0xb763936b in _Unwind_RaiseException () from /lib/libgcc_s.so.1 #5 0xb76d0304 in __cxa_throw () from /usr/lib/libstdc++.so.6 #6 0x080486c1 in main () when run on the host with proper ld-linux.so and run paths the stack trace is as follows: #0 0xb7fdc424 in __kernel_vsyscall () #1 0xb7d4073f in raise () from /opt/gnl/usr/i686-gnl-linux-gnu/sysroot/lib/libc.so.6 #2 0xb7d41c5e in abort () from /opt/gnl/usr/i686-gnl-linux-gnu/sysroot/lib/libc.so.6 #3 0xb7ecf0d9 in uw_init_context_1 (context=context@entry=0xbfffe680, outer_cfa=outer_cfa@entry=0xbfffe860, outer_ra=0xb7f66424 <__cxxabiv1::__cxa_throw(void*, std: :type_info*, void (*)(void*))+97>) at ../../../libgcc/unwind-dw2.c:1567 #4 0xb7ecf40a in _Unwind_RaiseException (exc=0x804a048) at ../../../libgcc/unwind.inc:88 #5 0xb7f66424 in __cxxabiv1::__cxa_throw (obj=0x804a068, tinfo=0x8049e50 <_ZTIi@@CXXABI_1.3>, dest=0x0) at ../../../../libstdc++-v3/libsupc++/eh_throw.cc:82 #6 0x08048924 in main () at dupa.cpp:8 In the discussion with tom_kos and wbx on IRC we managed to pin the problem libgcc_s.so. The problem only appears when linking with dynamic libgcc_s.so. If the program is compiled with -static-libgcc it runs correctly.
Which gcc version was used for the test? It can be useful to be able to match libgcc/unwind-dw2.c:1567 from the backtrace with the appropriate source code.
It comes from 4.9.0.
Please also provide your .config file so other people can try to look at the problem.
Created attachment 5456 [details] Buildroot configuration
The difference between compiling with -static-libgcc seems to boil down to the following function: _Unwind_Find_FDE When compiled with -statlic-libgcc the function invocation ends up in glibc. When -static-libgcc is not given, then this function is located in libgcc.
It turns out that 900-musl-support.patch breaks exceptions when using glibc: The proper exception handling in libgcc seems to need USE_PT_GNU_EH_FRAME definition in libgcc's unwind-dw2-fde-dip.c. However; the patch changes this file to: +#if !defined(inhibit_libc) && defined(HAVE_LD_EH_FRAME_HDR) && defined(TARGET_DL_ITERATE_PHDR) # define USE_PT_GNU_EH_FRAME Configure in host-gcc-final seems to be unable to locate TARGET_DL_ITERATE_PHDR: checking dl_iterate_phdr in target C library... unknown In such case unwind-dw2-fde-dip.c falls back to unwind-dw2-fde.c which does not do the job of finding a FDE and hence the crash.
Thanks a lot for the debugging! I'll have a closer look and see what is the appropriate solution to make sure that C++ exceptions work with glibc, and that we can still enable musl.
Hi, there is a discussion about this problem on the musl mailing list. Just if you are not subscribed.
IMHO a good solution would be to make patches conditional in some cases, e.g. only use 900-musl-support.patch if C library is selected to musl. I guess it would require quite amount of work thought...
(In reply to comment #8) > there is a discussion about this problem on the musl mailing list. > Just if you are not subscribed. Right, but I don't see our specific problem being taken into account. Rich Felker concluded the thread with: """ Please note that these changes are not mandatory; at present, everything works, but crtbegin.o and crtend.o are unnecessarily bloated and this affects static binary size. """ Maybe we should tell him that the changes are breaking C++ exception handling for glibc, when the musl patches are applied to gcc?
(In reply to comment #9) > IMHO a good solution would be to make patches conditional in some cases, e.g. > only use 900-musl-support.patch if C library is selected to musl. I guess it > would require quite amount of work thought... That's certainly a solution, but I wouldn't qualify it as a good solution. We try really hard to avoid having conditional patches. Though, as a temporary solution it would certainly be acceptable. This problem is a major bug in Buildroot 2014.05, and we have to solve it somehow.
The relevant part of the musl patch is intended to remove the hard-coding of USE_PT_GNU_EH_FRAME as glibc-specific and instead detect via configure that it should be used. My guess is that something's broken in the configure script whereby TARGET_DL_ITERATE_PHDR is not getting detected correctly; perhaps the test is not cross-compiler-compatible. Based on the thread on the musl mailing list (http://www.openwall.com/lists/musl/2014/06/16/2), I think if this is the problem it would go undetected by musl, since when targetting musl gcc is still producing an "old-style" crtbegin/crtend that works without USE_PT_GNU_EH_FRAME. With glibc that doesn't happen because the crtstuff preprocessor conditionals are still hard-coded for glibc. In my opinion the "right" fix is finding and fixing whatever's wrong in configure, but as a short-term solution, the conditional could be fixed to hard-code USE_PT_GNU_EH_FRAME for glibc while detecting it elsewhere, as in: +#if (!defined(inhibit_libc) && defined(HAVE_LD_EH_FRAME_HDR) && defined(TARGET_DL_ITERATE_PHDR)) || defined(__gnu_linux__) # define USE_PT_GNU_EH_FRAME or something closer to whatever the upstream logic is for glibc.
If I'm looking at the right place, TARGET_DL_ITERATE_PHDR is defined in output/build/host-gcc-final-4.9.0/gcc/configure.ac at line 5079. It looks like it only gets set on a variant of solaris2. So this variable looks like a quick hack to me rather than something one can depend on.
We are seeing the same problem with gcc 4.8.2 on our i586 platform. Code that uses C++ exceptions and which used to work fine with the buildroot 2014.02 release now aborts when an exception is thrown.
(In reply to comment #14) > We are seeing the same problem with gcc 4.8.2 on our i586 platform. Code that > uses C++ exceptions and which used to work fine with the buildroot 2014.02 > release now aborts when an exception is thrown. I have now verified that the problem goes away if I revert the commit that introduces musl support to gcc 4.8.2.
Created attachment 5528 [details] Buildroot configuration
Created attachment 5534 [details] C code using pthread_exit
Hi, The 900-musl-support.patch also breaks the pthread_exit() function in pure C-code. I enclose two files : - basic buildroot configuration, toolchain using gcc 4.8.1 / glibc 2.18 / binutils 2.22 - basic C code creating a thread that kills itself using pthread_exit() Using a toolchain built from master, the main process receives the SIGABRT signal. If I remove the 900-musl-support.patch and rebuild the whole buildroot, the code exits normally.
What to do with this bug? We need a proper solution for the upcoming release...
Re-assigning to me, I'm working on it now.
The patch series fixing this has now been applied: http://git.buildroot.net/buildroot/commit/?id=fea35ce67317aa0eee678fb9440814d1346fb2fb