libstdc++ registers some handlers with pthreads in conjunction with throw statements. Those handlers are not properly removed when libstdc++ is unloaded, causing pthread_join to jump to a bad address.
gcc -ldl -lpthread main.c -o main g++ -shared -lstdc++ -lc -lm plug.cc \ -o plug.so ./main In plug. Leaving plug. make: *** [all] Killed gdb: [EMAIL PROTECTED]:~/svn/bug905$ gdb main GNU gdb 6.3-debian Copyright 2004 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB. Type "show warranty" for details. This GDB was configured as "i386-linux"...Using host libthread_db library "/usr/lib/debug/libthread_db.so.1". (gdb) run Starting program: /home/grothoff/svn/bug905/main [Thread debugging using libthread_db enabled] [New Thread 16384 (LWP 2816)] [New Thread 32769 (LWP 2819)] [New Thread 16386 (LWP 2821)] In plug. Leaving plug. Program received signal SIGSEGV, Segmentation fault. [Switching to Thread 16386 (LWP 2821)] 0x557982a0 in ?? () (gdb) ba #0 0x557982a0 in ?? () #1 0x55579f08 in __pthread_destroy_specifics () at specific.c:192 #2 0x555764d5 in __pthread_do_exit (retval=0x804cf18, currentframe=0x804cf18 "") at join.c:43 #3 0x55576e5d in pthread_start_thread (arg=0xff7ffbe0) at manager.c:312 #4 0x55576ecf in pthread_start_thread_event (arg=0xff7ffbe0) at manager.c:333 #5 0x5569992a in clone () from /usr/lib/debug/libc.so.6 Additional information about the original context is tracked in GNUnet's Mantis bug database at https://gnunet.org/mantis/view.php?id=905 Environment: System: Linux elma 2.6.8-11-amd64-k8 #1 Mon May 30 22:15:15 UTC 2005 x86_64 GNU/Linux Architecture: x86_64 (also reproduced on i686) host: i486-pc-linux-gnu build: i486-pc-linux-gnu target: i486-pc-linux-gnu configured with: ../src/configure -v --enable-languages=c,c++,java,f77,pascal,objc,ada,treelang --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-gxx-include-dir=/usr/include/c++/3.3 --enable-shared --enable-__cxa_atexit --with-system-zlib --enable-nls --without-included-gettext --enable-clocale=gnu --enable-debug --enable-java-gc=boehm --enable-java-awt=xlib --enable-objc-gc i486-linux How-To-Repeat: Essentially, use C code that is NOT linked against libstdc++ to create a pthread. In that thread dlopen a C++ library, dlsym a function that throws and catches an exception, close the library. In the main C code join on the pthread. The join will segfault after the C++ code is complete and the library is unloaded. https://gnunet.org/svn/bug905/ has 60 lines of C and C++ code (plus a trivial Makefile) to reproduce. What seems to happen is this. libstdc++ registers some on-exit handler with the pthread which refers to code in libstdc++. The library _fails_ to unregister that handler when libstdc++ itself is unloaded. The library is unloaded, the handler is still there, and on pthread_join the handler is called and points to a (now invalid) address in memory => seg fault. The bug was found in real-life in GNUnet (100% C, multithreaded) loading a C plugin which uses libextractor (reentrant) which loads a C++ plugin which uses exceptions. ------- Additional Comments From grothoff at gnunet dot org 2005-08-27 04:42 ------- Fix: Workarounds: LD_PRELOAD libstdc++ (then the symbol stays in memory) do not use pthreads (no exit handler) do not use plugins (no unloading issue) do not use exceptions (no handler registered) link the C code against libstdc++ (handler stays in memory on unload of plugin) do not use libstdc++ (yeah, right) None of these is acceptable for me since C code that may load a plugin that may load a plugin that may use C++ that may use exceptions should not require C++ to be even _installed_, not to mention link against it. The solution is to properly track installed handlers and unregister those in the destructor of the library (ELF has wonderful provisions for that). -- Summary: exceptions in plugins in threads cause segmentation violation by leaving bad exit handler for the pthread Product: gcc Version: 3.3.5 Status: UNCONFIRMED Severity: normal Priority: P3 Component: libstdc++ AssignedTo: unassigned at gcc dot gnu dot org ReportedBy: grothoff at gnunet dot org CC: gcc-bugs at gcc dot gnu dot org GCC build triplet: i486-pc-linux-gnu GCC host triplet: i486-pc-linux-gnu GCC target triplet: i486-pc-linux-gnu http://gcc.gnu.org/bugzilla/show_bug.cgi?id=23591