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,, 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
- 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()

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.
Target: i386-pc-solaris2.10
Configured with: ../src/gcc-4.6.2/configure
--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/
#1 0xfd45365e in cond_sleep_queue () from /lib/
#2 0xfd453817 in cond_wait_queue () from /lib/
#3 0xfd453b94 in cond_wait_common () from /lib/
#4 0xfd453d02 in _cond_wait () from /lib/
#5 0xfd453d2d in cond_wait () from /lib/
#6 0xfd453d66 in pthread_cond_wait () from /lib/
#7 0xfd632898 in __gthread_cond_wait (g=0xfd822ea8) at
#8 __gthread_cond_wait_recursive (g=0xfd822ea8) at
#9 __gnu_cxx::__cond::wait_recursive (g=0xfd822ea8) at
#10 __cxa_guard_acquire (g=0xfd822ea8) at
= Reentrant call to boost::system::generic_category()
#11 0xfd812313 in boost::system::generic_category () at
#12 0xfe85cd38 in
__priority=65535) at ./boost/system/error_code.hpp:214
#13 0xfe85d05f in _GLOBAL__sub_I_instantiate_re2c_lexer_str.cpp () at
= static initization of boost.wave library
#14 0xfe8868fd in __do_global_ctors_aux () from
#15 0xfe88692a in _init () from
#16 0xfefce37e in call_init () from /usr/lib/
#17 0xfefce1cf in is_dep_init () from /usr/lib/
#18 0xfefdaa4b in elf_bndr () from /usr/lib/
#19 0xfefc2ab4 in elf_rtbndr () from /usr/lib/
#20 0xfee60688 in ?? ()
#21 0xfee0c8f6 in
at ./boost/exception/detail/exception_ptr.hpp:119
#22 0xfee0c0d2 in
__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
#25 0xfee0d9ba in _init () from
#26 0xfefce37e in call_init () from /usr/lib/
#27 0xfefce1cf in is_dep_init () from /usr/lib/
#28 0xfefdaa4b in elf_bndr () from /usr/lib/
#29 0xfefc2ab4 in elf_rtbndr () from /usr/lib/
#30 0xfdce0688 in ?? ()
= First calll to boost::system::generic_category()
#31 0xfd81232a in boost::system::generic_category () at
#32 0xfd812386 in
__priority=65535) at ./boost/system/error_code.hpp:214
#33 0xfd8123ed in _GLOBAL__sub_I_error_code.cpp () at
= static initialization of boost.system
#34 0xfd8126ed in __do_global_ctors_aux () from
#35 0xfd81271a in _init () from
#36 0xfefce37e in call_init () from /usr/lib/
#37 0xfefcd7d5 in setup () from /usr/lib/
#38 0xfefdba3e in _setup () from /usr/lib/
#39 0xfefc299c in _rt_boot () from /usr/lib/
#40 0x08047540 in ?? ()
#41 0x08047670 in ?? ()

More thanks for reading all.

Boost list run by bdawes at, gregod at, cpdaniel at, john at