There is a problem with _S_destroy_thread_key when loading dynamic libraries. This function will be called when thread finishes. But unfortunatelly when using dynamic libraries the code might be removed from memory using dlclose(). After that thread that has been modifing stl containers inside dynamic library will finish with SEGV. Probably the best solution would be to make this method static and move it's body to shared library or enable manual thread detachment.
Do you have a simple example, in a way this might be your bug as you dlclose before libstdc++ has finished its job.
I have used following scenario: 1. dlopen dynamic library 2. execute a method inside dynamic library which addes integer to vector 3. dlclose 4. try to exit cleanly Program crashes with SIGSEGV.
We are talking about a 3.4.0 library non-standard configured, i.e., using --enable-libstdcxx-allocator=mt at build time, right? In 3.4.0 the new mt allocator was still very rough, and now, in mainline, many important details have changes (for one, the function at issue is in src!). I wholeheartedly suggest testing the latter...
Created attachment 7930 [details] current mt_allocator include
Created attachment 7931 [details] current mt_allocator source file
here. I'll make it really easy for you to check. I'm pretty sure this is fixed in the current code, but your analysis would be appreciated before we close this report. To move this newer version to the 3.4.x branch, we'll have to rename it. That's being seriously considered. best, -benjamin
I cannot check proposed changes because of compilation problems. I have changed makefiles in libstdc++/src directory but I am getting errors while linking: /remote/beta4/lukasz/gcc2/gcc/g++ -shared-libgcc -B/remote/beta4/lukasz/gcc2/gcc/ -nostdinc++ -B/remote/beta4/lukasz/gcc-3.4/i686-pc-linux-gnu/bin/ -B/remote/beta4/lukasz/gcc-3.4/i686-pc-linux-gnu/lib/ -isystem /remote/beta4/lukasz/gcc-3.4/i686-pc-linux-gnu/include -isystem /remote/beta4/lukasz/gcc-3.4/i686-pc-linux-gnu/sys-include -g -O2 -D_GLIBCXX_ASSERT -ffunction-sections -fdata-sections -fmessage-length=0 -DLOCALEDIR=/remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/po/share/locale -g -O2 -D_GNU_SOURCE -o abi_check abi_check.o -L/remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/src -L/remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/src/.libs -lv3test -L/remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite -lm -Wl,--rpath -Wl,/remote/beta4/lukasz/gcc2/gcc -Wl,--rpath -Wl,/remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/src/.libs /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite/libv3test.a(testsuite_abi.o)(.gnu.linkonce.t._ZN9__gnu_cxx10__mt_allocISsNS_20__common_pool_policyINS_6__poolELb1EEEE10deallocateEPSsj+0x74): In function `compare_symbols': /remote/beta4/lukasz/gcc-3.4.3/libstdc++-v3/libsupc++/new:92: undefined reference to `__gnu_cxx::__pool<true>::_M_reclaim_block(char*, unsigned int)' /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite/libv3test.a(testsuite_abi.o)(.gnu.linkonce.t._ZN9__gnu_cxx10__mt_allocIPSsNS_20__common_pool_policyINS_6__poolELb1EEEE10deallocateEPS1_j+0x74):/remote/beta4/lukasz/gcc-3.4.3/libstdc++-v3/libsupc++/new:92: undefined reference to `__gnu_cxx::__pool<true>::_M_reclaim_block(char*, unsigned int)' /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite/libv3test.a(testsuite_abi.o)(.gnu.linkonce.t._ZN9__gnu_cxx10__mt_allocISt4pairI6symbolS2_ENS_20__common_pool_policyINS_6__poolELb1EEEE10deallocateEPS3_j+0x74):/remote/beta4/lukasz/gcc-3.4.3/libstdc++-v3/libsupc++/new:92: undefined reference to `__gnu_cxx::__pool<true>::_M_reclaim_block(char*, unsigned int)' /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite/libv3test.a(testsuite_abi.o)(.gnu.linkonce.t._ZN9__gnu_cxx10__mt_allocISsNS_20__common_pool_policyINS_6__poolELb1EEEE8allocateEjPKv+0x73): In function `compare_symbols': /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:269: undefined reference to `__gnu_cxx::__pool<true>::_M_get_thread_id()' /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite/libv3test.a(testsuite_abi.o)(.gnu.linkonce.t._ZN9__gnu_cxx10__mt_allocISsNS_20__common_pool_policyINS_6__poolELb1EEEE8allocateEjPKv+0x196): In function `compare_symbols': /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/include/bits/stl_construct.h:107: undefined reference to `__gnu_cxx::__pool<true>::_M_reserve_block(unsigned int, unsigned int)' /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite/libv3test.a(testsuite_abi.o)(.gnu.linkonce.t._ZN9__gnu_cxx10__mt_allocIPNS_15_Hashtable_nodeISt4pairIKSs6symbolEEENS_20__common_pool_policyINS_6__poolELb1EEEE10deallocateEPS7_j+0x74): In function `compare_symbols': /remote/beta4/lukasz/gcc-3.4.3/libstdc++-v3/libsupc++/new:92: undefined reference to `__gnu_cxx::__pool<true>::_M_reclaim_block(char*, unsigned int)' /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite/libv3test.a(testsuite_abi.o)(.gnu.linkonce.t._ZN9__gnu_cxx10__mt_allocINS_15_Hashtable_nodeISt4pairIKSs6symbolEEENS_20__common_pool_policyINS_6__poolELb1EEEE10deallocateEPS6_j+0x74):/remote/beta4/lukasz/gcc-3.4.3/libstdc++-v3/libsupc++/new:92: undefined reference to `__gnu_cxx::__pool<true>::_M_reclaim_block(char*, unsigned int)' /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite/libv3test.a(testsuite_abi.o)(.gnu.linkonce.t._ZN9__gnu_cxx10__mt_allocISt4pairI6symbolS2_ENS_20__common_pool_policyINS_6__poolELb1EEEE8allocateEjPKv+0x72): In function `compare_symbols': /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/include/bits/stl_iterator_base_types.h:165: undefined reference to `__gnu_cxx::__pool<true>::_M_get_thread_id()' /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite/libv3test.a(testsuite_abi.o)(.gnu.linkonce.t._ZN9__gnu_cxx10__mt_allocISt4pairI6symbolS2_ENS_20__common_pool_policyINS_6__poolELb1EEEE8allocateEjPKv+0x193): In function `compare_symbols': /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/include/bits/stl_iterator.h:623: undefined reference to `__gnu_cxx::__pool<true>::_M_reserve_block(unsigned int, unsigned int)' /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite/libv3test.a(testsuite_abi.o)(.gnu.linkonce.t._ZN9__gnu_cxx10__mt_allocINS_15_Hashtable_nodeISt4pairIKSs6symbolEEENS_20__common_pool_policyINS_6__poolELb1EEEE8allocateEjPKv+0x71): In function `compare_symbols': /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:261: undefined reference to `__gnu_cxx::__pool<true>::_M_get_thread_id()' /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite/libv3test.a(testsuite_abi.o)(.gnu.linkonce.t._ZN9__gnu_cxx10__mt_allocINS_15_Hashtable_nodeISt4pairIKSs6symbolEEENS_20__common_pool_policyINS_6__poolELb1EEEE8allocateEjPKv+0x193): In function `compare_symbols': /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/include/bits/stl_iterator.h:623: undefined reference to `__gnu_cxx::__pool<true>::_M_reserve_block(unsigned int, unsigned int)' /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite/libv3test.a(testsuite_abi.o)(.gnu.linkonce.t._ZN9__gnu_cxx10__mt_allocIPSsNS_20__common_pool_policyINS_6__poolELb1EEEE8allocateEjPKv+0x73): In function `compare_symbols': /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:269: undefined reference to `__gnu_cxx::__pool<true>::_M_get_thread_id()' /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite/libv3test.a(testsuite_abi.o)(.gnu.linkonce.t._ZN9__gnu_cxx10__mt_allocIPSsNS_20__common_pool_policyINS_6__poolELb1EEEE8allocateEjPKv+0x194):/remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:261: undefined reference to `__gnu_cxx::__pool<true>::_M_reserve_block(unsigned int, unsigned int)' /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite/libv3test.a(testsuite_abi.o)(.gnu.linkonce.t._ZN9__gnu_cxx10__mt_allocIPNS_15_Hashtable_nodeISt4pairIKSs6symbolEEENS_20__common_pool_policyINS_6__poolELb1EEEE8allocateEjPKv+0x73):/remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:269: undefined reference to `__gnu_cxx::__pool<true>::_M_get_thread_id()' /remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/testsuite/libv3test.a(testsuite_abi.o)(.gnu.linkonce.t._ZN9__gnu_cxx10__mt_allocIPNS_15_Hashtable_nodeISt4pairIKSs6symbolEEENS_20__common_pool_policyINS_6__poolELb1EEEE8allocateEjPKv+0x194):/remote/beta4/lukasz/gcc2/i686-pc-linux-gnu/libstdc++-v3/include/bits/basic_string.h:261: undefined reference to `__gnu_cxx::__pool<true>::_M_reserve_block(unsigned int, unsigned int)' collect2: ld returned 1 exit status You would have to tell me how should I configure gcc-3.4.3 makefiles to compile it with mt_allocator.cc.
> You would have to tell me how should I configure gcc-3.4.3 makefiles to compile > it with mt_allocator.cc. Unfortunately, that will not suffice, I'm afraid. In order to actually use the current mt_allocator with 3.4 you have also to change some exports in config/linker-map.gnu. All in all, probably the easiest path is actually testing a snapshot of 4.0: each week a new one is available as a tarball, or you can use CVS.
I can confirm this (unfortunately, haha). $ g++ --version g++ (GCC) 3.4.4 20041218 (prerelease) (Debian 3.4.3-6) $ g++ -v 2>&1 | grep -- '--enable-libstdcxx-allocator=mt' Configured with: ../src/configure -v --enable-languages=c,c++,java,f77,pascal,objc,ada,treelang --prefix=/usr --libexecdir=/usr/lib --with-gxx-include-dir=/usr/include/c++/3.4 --enable-shared --with-system-zlib --enable-nls --without-included-gettext --program-suffix=-3.4 --enable-__cxa_atexit --enable-libstdcxx-allocator=mt --enable-clocale=gnu --enable-libstdcxx-debug --enable-java-gc=boehm --enable-java-awt=gtk --disable-werror i486-linux This small testcase should crash with 3.4 and the mt_allocator: http://dc.selwerd.nl/dlcrash.tar.bz2 I don't know how this generally goes, but is it possible to get a fix back into 3.4? Thanks, Walter
(In reply to comment #9) > I can confirm this (unfortunately, haha). hmm, --save-temps option produces totally diff. plugin and behaviuor :O this is really amazing. # make clean all OPT="-O" rm -f dltest *.o *.ii *.s g++ -Wall -g -O -c -o dltest.o dltest.cc g++ -Wall -g -O -lpthread -ldl -Wl,--export-dynamic -Wall dltest.o -o dltest g++ -Wall -g -O -shared -o plugin.o plugin.cc -rwx------ 1 pluto users 23062 Mar 24 14:08 dltest -rw------- 1 pluto users 19520 Mar 24 14:08 dltest.o -rwx------ 1 pluto users 80645 Mar 24 14:08 plugin.o # ./dltest Segmentation fault # make clean all OPT="-O --save-temps" rm -f dltest *.o *.ii *.s g++ -Wall -g -O --save-temps -c -o dltest.o dltest.cc g++ -Wall -g -O --save-temps -lpthread -ldl -Wl,--export-dynamic -Wall dltest.o -o dltest g++ -Wall -g -O --save-temps -shared -o plugin.o plugin.cc -rwx------ 1 pluto users 23062 Mar 24 14:09 dltest -rw------- 1 pluto users 19520 Mar 24 14:09 dltest.o -rwx------ 1 pluto users 5436 Mar 24 14:09 plugin.o # ./dltest ./plugin.o: undefined symbol: entry
Subject: Bug 19265 CVSROOT: /cvs/gcc Module name: gcc Changes by: bkoz@gcc.gnu.org 2005-09-12 04:49:11 Modified files: libstdc++-v3 : ChangeLog libstdc++-v3/config: linker-map.gnu libstdc++-v3/include/ext: mt_allocator.h libstdc++-v3/src: mt_allocator.cc libstdc++-v3/testsuite/lib: dg-options.exp libstdc++.exp Added files: libstdc++-v3/testsuite: testsuite_shared.cc libstdc++-v3/testsuite/ext/mt_allocator: 22309_thread.cc Log message: 2005-09-11 Benjamin Kosnik <bkoz@redhat.com> PR libstdc++/19265 PR libstdc++/22309 * include/ext/mt_allocator.h (__gnu_cxx::__create_handler): Remove. (__pool<true>::_M_destroy_thread_key): Compatibility only. (__pool<true>::_M_initialize(__destroy): Same. (__pool<true>::_M_initialize): New. (__pool<true>::_M_initialize_once): Nothing fancy. (__pool<true>::_M_once): Remove. (__common_pool): New. (__common_pool_base): New. (__per_type_pool): New. (__per_type_pool_base): New. * src/mt_allocator.cc: Same. * config/linker-map.gnu (__pool<true>::_M_initialize()): Add. 2005-09-11 Jakub Jelinek <jakub@redhat.com> PR libstdc++/19265 PR libstdc++/22309 * src/mt_allocator.cc (__gnu_internal::freelist_mutex): Make static. (__gnu_internal::__freelist): New type. (__gnu_internal::freelist): New variable. (__gnu_internal::_M_destroy_thread_key): New function. (__gnu_cxx::__pool<true>::_M_destroy): Don't delete _M_thread_freelist_initial. (__gnu_cxx::__pool<true>::_M_initialize): Make argument nameless. Don't use _M_thread_freelist and _M_thread_freelist_initial __pool<true> fields, instead use __gnu_internal::freelist fields, call gthread_key_create just once. Use __gnu_internal::_M_destroy_thread_key as key destructor. (__gnu_cxx::__pool<true>::_M_get_thread_id): Store size_t id rather than _Thread_record* in the thread specific value. Don't use _M_thread_freelist __pool<true> field, instead use __gnu_internal::freelist fields. (__gnu_cxx::__pool<true>::_M_destroy_thread_key): Do nothing. 2005-09-11 Benjamin Kosnik <bkoz@redhat.com> Jakub Jelinek <jakub@redhat.com> PR libstdc++/19265 PR libstdc++/22309 * testsuite/testsuite_shared.cc: New. * testsuite/lib/dg-options.exp (dg-require-sharedlib): New. * testsuite/lib/libstdc++.exp (libstdc++_init): Look for shared library, and set v3-sharedlib based on this. (check_v3_target_sharedlib): New. (proc v3-build_support): Build shared objects. * testsuite/ext/mt_allocator/22309_thread.cc: New, use above. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/ChangeLog.diff?cvsroot=gcc&r1=1.3095&r2=1.3096 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/config/linker-map.gnu.diff?cvsroot=gcc&r1=1.84&r2=1.85 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/ext/mt_allocator.h.diff?cvsroot=gcc&r1=1.47&r2=1.48 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/src/mt_allocator.cc.diff?cvsroot=gcc&r1=1.12&r2=1.13 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/testsuite_shared.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/ext/mt_allocator/22309_thread.cc.diff?cvsroot=gcc&r1=NONE&r2=1.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/lib/dg-options.exp.diff?cvsroot=gcc&r1=1.4&r2=1.5 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/testsuite/lib/libstdc++.exp.diff?cvsroot=gcc&r1=1.45&r2=1.46
This should be solved with 22309. I'd like to consolidate the bug reports to 22309, and am closing this one.
*** This bug has been marked as a duplicate of 22309 ***
Subject: Bug 19265 CVSROOT: /cvs/gcc Module name: gcc Branch: gcc-4_0-branch Changes by: bkoz@gcc.gnu.org 2005-09-20 05:24:50 Modified files: libstdc++-v3 : ChangeLog libstdc++-v3/config: linker-map.gnu libstdc++-v3/include/ext: mt_allocator.h libstdc++-v3/src: debug.cc locale_init.cc mt_allocator.cc pool_allocator.cc Log message: 2005-09-19 Benjamin Kosnik <bkoz@redhat.com> PR libstdc++/19265 PR libstdc++/22309 * include/ext/mt_allocator.h (__gnu_cxx::__create_handler): Remove. (__pool<true>::_M_destroy_thread_key): Compatibility only. (__pool<true>::_M_initialize(__destroy): Same. (__pool<true>::_M_initialize): New. (__pool<true>::_M_initialize_once): Nothing fancy. (__pool<true>::_M_once): Remove. (__common_pool): New. (__common_pool_base): New. (__per_type_pool): New. (__per_type_pool_base): New. * src/mt_allocator.cc: Same. * config/linker-map.gnu (__pool<true>::_M_initialize()): Add. 2005-09-19 Jakub Jelinek <jakub@redhat.com> PR libstdc++/19265 PR libstdc++/22309 * src/mt_allocator.cc (__gnu_internal::freelist_mutex): Make static. (__gnu_internal::__freelist): New type. (__gnu_internal::freelist): New variable. (__gnu_internal::_M_destroy_thread_key): New function. (__gnu_cxx::__pool<true>::_M_destroy): Don't delete _M_thread_freelist_initial. (__gnu_cxx::__pool<true>::_M_initialize): Make argument nameless. Don't use _M_thread_freelist and _M_thread_freelist_initial __pool<true> fields, instead use __gnu_internal::freelist fields, call gthread_key_create just once. Use __gnu_internal::_M_destroy_thread_key as key destructor. (__gnu_cxx::__pool<true>::_M_get_thread_id): Store size_t id rather than _Thread_record* in the thread specific value. Don't use _M_thread_freelist __pool<true> field, instead use __gnu_internal::freelist fields. (__gnu_cxx::__pool<true>::_M_destroy_thread_key): Do nothing. 2005-09-19 Benjamin Kosnik <bkoz@redhat.com> Jakub Jelinek <jakub@redhat.com> * src/debug.cc (iterator_base_mutex): Make static for internal linkage. * src/locale_init.cc (locale_mutex): Same. * src/mt_allocator.cc (freelist_mutex): Same. * src/pool_allocator.cc (palloc_init_mutex): Same. Patches: http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.2917.2.83&r2=1.2917.2.84 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/config/linker-map.gnu.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.78.2.3&r2=1.78.2.4 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/include/ext/mt_allocator.h.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.45.8.1&r2=1.45.8.2 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/src/debug.cc.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.10&r2=1.10.18.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/src/locale_init.cc.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.15&r2=1.15.36.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/src/mt_allocator.cc.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.8&r2=1.8.22.1 http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libstdc++-v3/src/pool_allocator.cc.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.2&r2=1.2.24.1