Boost logo

Boost :

Subject: [boost] Static initialization of boost shared objects question
From: Juan Carlos Franzoy (jfranzoy_at_[hidden])
Date: 2013-01-25 14:19:18


Hello. Thanks for reading my question.

I fell into a deadlock in static initialization of boost shared objects.

The deadlock occurs in a reentrant call to a function which contains a
definition of a static variable.
Apparenlty gcc protects the initialization of such variables with a
condition variable.

Looking at the c++ code nothing at all make anybody suspect about reentrancy.

My "interpretation of the fact" may be titled 'something in gcc, ld,
ld.so, c++language made the call to be reentrant'

- There is a function boost::system::generic_category() that has a
static variable V
- V type is boost::system::annonymous-namespace::generic_error_category
- boost::system::annonymous-namespace::generic_error_category is
subclass of boost::system::error_category.
- boost::system::annonymous-namespace::generic_error_category has no
declared/defined constructor as well as all its superclasses
- The compilation process generate the constructor
boost::system::error_category::error_category() as a weak symbol
inside every shared object that uses it.
- There is a static variable boost::system::posix_category in one of
the shared objects that is initialized calling
boost::system::generic_category().
- when the static initialization of a shared object
boost::system::posix_category get initialized
- which calls boost::system::generic_category()
- Inside boost::system::generic_category() starts the initialization
of V which calls boost::system::error_category::error_category()
- It may happend that the runtime calls an instance of
boost::system::error_category::error_category() that resides in a
shared object that is still not loaded
- So that .so get loaded and it is called its own static initialization
- which can call boost::system::generic_category()
- BOOM

I would love if you can confirm of refute my humble "interpretation".

Details follows
-------------------

boost version: 1-52-0

Operating system: uname -a
SunOS bcpp-solaris10 5.10 Generic_147441-25 i86pc i386 i86pc

$ gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/export/home/local/gcc-4.6.2/libexec/gcc/i386-pc-solaris2.10/4.6.2/lto-wrapper
Target: i386-pc-solaris2.10
Configured with: ../src/gcc-4.6.2/configure
--prefix=/export/home/local/gcc-4.6.2
--with-gmp=/export/home/local/gcc-4.6.2/gmp-4.3.2
--with-mpfr=/export/home/local/gcc-4.6.2/mpfr-3.0.0
--with-mpc=/export/home/local/gcc-4.6.2/mpc-0.8.2
--with-libelf=/export/home/local/gcc-4.6.2/libelf-0.8.12
--enable-shared --enable-threads=posix --enable-checking=release
--with-system-zlib --enable-__cxa_atexit --enable-languages=c,c++
--with-as=/usr/local/bin/as --with-gnu-as --with-ld=/usr/ccs/bin/ld
--without-gnu-ld --enable-plugin --enable-multilib
--enable-version-specific-runtime-libs --enable-bootstrap --enable-ssp
--enable-libssp --with-included-gettext --enable-lto
--host=i386-pc-solaris2.10 --build=i386-pc-solaris2.10
Thread model: posix
gcc version 4.6.2 (GCC)

Callstack backtrace (lines begining with = are my comments):
=
= deadlock here: the threads is waiting itself
=
#0 0xfd459019 in __lwp_park () from /lib/libc.so.1
#1 0xfd45365e in cond_sleep_queue () from /lib/libc.so.1
#2 0xfd453817 in cond_wait_queue () from /lib/libc.so.1
#3 0xfd453b94 in cond_wait_common () from /lib/libc.so.1
#4 0xfd453d02 in _cond_wait () from /lib/libc.so.1
#5 0xfd453d2d in cond_wait () from /lib/libc.so.1
#6 0xfd453d66 in pthread_cond_wait () from /lib/libc.so.1
#7 0xfd632898 in __gthread_cond_wait (g=0xfd822ea8) at
...build-gcc/out/i386-pc-solaris2.10/libstdc++-v3/include/i386-pc-solaris2.10/bits/gthr-default.h:846
#8 __gthread_cond_wait_recursive (g=0xfd822ea8) at
...work/build-gcc/out/i386-pc-solaris2.10/libstdc++-v3/include/i386-pc-solaris2.10/bits/gthr-default.h:860
#9 __gnu_cxx::__cond::wait_recursive (g=0xfd822ea8) at
...build-gcc/out/i386-pc-solaris2.10/libstdc++-v3/include/ext/concurrence.h:377
#10 __cxa_guard_acquire (g=0xfd822ea8) at
.../src/gcc-4.6.2/libstdc++-v3/libsupc++/guard.cc:289
=
= Reentrant call to boost::system::generic_category()
=
#11 0xfd812313 in boost::system::generic_category () at
libs/system/src/error_code.cpp:425
#12 0xfe85cd38 in
__static_initialization_and_destruction_0(__initialize_p=1,
__priority=65535) at ./boost/system/error_code.hpp:214
#13 0xfe85d05f in _GLOBAL__sub_I_instantiate_re2c_lexer_str.cpp () at
libs/wave/src/instantiate_re2c_lexer_str.cpp:56
=
= static initization of boost.wave library
=
#14 0xfe8868fd in __do_global_ctors_aux () from
...boost/lib/libboost_wave-gcc46-mt-d-32-SOLARIS-X86-1_52.so.1.52.0
#15 0xfe88692a in _init () from
...boost/lib/libboost_wave-gcc46-mt-d-32-SOLARIS-X86-1_52.so.1.52.0
#16 0xfefce37e in call_init () from /usr/lib/ld.so.1
#17 0xfefce1cf in is_dep_init () from /usr/lib/ld.so.1
#18 0xfefdaa4b in elf_bndr () from /usr/lib/ld.so.1
#19 0xfefc2ab4 in elf_rtbndr () from /usr/lib/ld.so.1
#20 0xfee60688 in ?? ()
#21 0xfee0c8f6 in
boost::exception_detail::get_static_exception_object<boost::exception_detail::bad_alloc_>()
at ./boost/exception/detail/exception_ptr.hpp:119
#22 0xfee0c0d2 in
__static_initialization_and_destruction_0(__initialize_p=1,
__priority=65535) at ./boost/exception/detail/exception_ptr.hpp:138
#23 0xfee0c271 in _GLOBAL__sub_I_future.cpp () at libs/thread/src/future.cpp:60
=
= static initization of boost.thread library
=
#24 0xfee0d98d in __do_global_ctors_aux () from
...boost/lib/libboost_thread-gcc46-mt-d-32-SOLARIS-X86-1_52.so.1.52.0
#25 0xfee0d9ba in _init () from
...boost/lib/libboost_thread-gcc46-mt-d-32-SOLARIS-X86-1_52.so.1.52.0
#26 0xfefce37e in call_init () from /usr/lib/ld.so.1
#27 0xfefce1cf in is_dep_init () from /usr/lib/ld.so.1
#28 0xfefdaa4b in elf_bndr () from /usr/lib/ld.so.1
#29 0xfefc2ab4 in elf_rtbndr () from /usr/lib/ld.so.1
#30 0xfdce0688 in ?? ()
=
= First calll to boost::system::generic_category()
=
#31 0xfd81232a in boost::system::generic_category () at
libs/system/src/error_code.cpp:425
#32 0xfd812386 in
__static_initialization_and_destruction_0(__initialize_p=1,
__priority=65535) at ./boost/system/error_code.hpp:214
#33 0xfd8123ed in _GLOBAL__sub_I_error_code.cpp () at
libs/system/src/error_code.cpp:430
=
= static initialization of boost.system
=
#34 0xfd8126ed in __do_global_ctors_aux () from
...boost/lib/libboost_system-gcc46-mt-d-32-SOLARIS-X86-1_52.so.1.52.0
#35 0xfd81271a in _init () from
...boost/lib/libboost_system-gcc46-mt-d-32-SOLARIS-X86-1_52.so.1.52.0
#36 0xfefce37e in call_init () from /usr/lib/ld.so.1
#37 0xfefcd7d5 in setup () from /usr/lib/ld.so.1
#38 0xfefdba3e in _setup () from /usr/lib/ld.so.1
#39 0xfefc299c in _rt_boot () from /usr/lib/ld.so.1
#40 0x08047540 in ?? ()
#41 0x08047670 in ?? ()

More thanks for reading all.


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk