Thanks for reading my question. I'm experiencing a dealock in the initialization of a static variable X defined inside a function Y called in the program static initialization. The problem, as far as I suppose ("as far as I know" would be an exaggeration), is that gcc protects the the expression that initializes X from it beeing initialized concurrently by another thread and Y get called reentrantly. The question to answer would be, why is Y called reentrantly? I think this problem relates to an old one I had in march 2010: http://gcc.gnu.org/ml/gcc-help/2010-03/msg00090.html. In that problem the deadlock was in my code and I could fix it. The 'real' problem I had to resolve arises using boost. In this case Y is boost::system::generic_category and X is a variable of type generic_error_category. I could reproduce the problem (well I suppose) although somewhat artificially using three small shared libraries and a lot of confused code. Details --------- 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) Details of the real problem using boost ---------------------------------------------------- Callstack backtrace (lines begining with = are my comments): = = deadlock 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 /export/home/bcpp/mlevalle/work/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 /export/home/bcpp/mlevalle/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 /export/home/bcpp/mlevalle/work/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 = = This seems to be a reentrant call to boost::system::generic_category(), although there is no reentrancy in the c++ code. = This function boost::system::generic_category() has an static variable inside whose constructor is empty (including all base class contructors) = = My humble interpretation is that gcc generates the empty constructor as a weak symbol in various of the boost libraries shared object, then at runtime = or link time one is chosen. That causes that error_code.cpp in boost_system.so triggers the load and static initialization of other boost shared = objects that ends up calling reentrantly the same function. = #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 #14 0xfe8868fd in __do_global_ctors_aux () from /export/home/bcpp/jfranzoy/nuevorep/BCPP/Modulos/legacy/boost/lib/libboost_wave-gcc46-mt-d-32-SOLARIS-X86-1_52.so.1.52.0 #15 0xfe88692a in _init () from /export/home/bcpp/jfranzoy/nuevorep/BCPP/Modulos/legacy/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 #24 0xfee0d98d in __do_global_ctors_aux () from /export/home/bcpp/jfranzoy/nuevorep/BCPP/Modulos/legacy/boost/lib/libboost_thread-gcc46-mt-d-32-SOLARIS-X86-1_52.so.1.52.0 #25 0xfee0d9ba in _init () from /export/home/bcpp/jfranzoy/nuevorep/BCPP/Modulos/legacy/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 ?? () = = This function boost::system::generic_category() has an static variable inside whose constructor is empty (including all base class contructors) = #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 #34 0xfd8126ed in __do_global_ctors_aux () from /export/home/bcpp/jfranzoy/nuevorep/BCPP/Modulos/legacy/boost/lib/libboost_system-gcc46-mt-d-32-SOLARIS-X86-1_52.so.1.52.0 #35 0xfd81271a in _init () from /export/home/bcpp/jfranzoy/nuevorep/BCPP/Modulos/legacy/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 ?? () Details of the artificial problem as I could reproduce -------------------------------------------------------------------- The files: *** a.hpp *** #ifndef AAA_HPP_INCLUDED #define AAA_HPP_INCLUDED #include <string> class AAA { std::string aaa_; public: explicit AAA(int i); int get() const; }; class DDD { int i_; public: DDD(); int get() const; }; extern DDD ddd; #endif /* AAA_HPP_INCLUDED */ *** end of a.hpp *** *** a.cpp *** #include <cerrno> #include <iostream> #include "a.hpp" #include "b.hpp" AAA::AAA(int i ) : aaa_( "PEPE" ) { std::cerr << "AAA::AAA(" << i << ")='" << this << "'" << std::endl; } int AAA::get() const { std::cerr << "AAA::get()='" << this << "'" << std::endl; return 10; } DDD::DDD() { std::cerr << "DDD::DDD()='" << this << "' bbb1(10)=" << bbb1(10) << std::endl; i_ = errno; } int DDD::get() const { return i_; } DDD ddd; *** end of a.cpp *** *** b.hpp *** #ifndef BBB_HPP_INCLUDED #define BBB_HPP_INCLUDED int bbb1(int i); #endif /* BBB_HPP_INCLUDED */ *** end of b.hpp *** *** b.cpp *** #include <iostream> #include "a.hpp" int bbb1(int i) { std::cerr << "bbb1(" << i << ")" << std::endl; static AAA a( i ); return a.get(); } *** end of b.cpp *** *** c.hpp *** #ifndef CCC_HPP_INCLUDED #define CCC_HPP_INCLUDED int ccc1(); #endif /* CCC_HPP_INCLUDED */ *** end of c.hpp *** *** c.cpp *** #include <iostream> #include "b.hpp" #include "c.hpp" class CCC { public: CCC() { std::cerr << "CCC::CCC()='" << this << "' bbb1(10)=" << bbb1(10) << std::endl; } }; CCC ccc; *** end of c.cpp *** *** d.cpp *** #include <iostream> #include "a.hpp" #include "b.hpp" int main() { return ddd.get(); } *** end of d.cpp *** The command to compile them: g++ -std=c++0x --shared -fPIC -O0 -oa.so -g a.cpp g++ -std=c++0x --shared -fPIC -O0 -ob.so -g b.cpp g++ -std=c++0x --shared -fPIC -O0 -oc.so -g c.cpp g++ -std=c++0x -fPIC -O0 -od c.so a.so b.so d.cpp The debugging session (comments start with =): solaris10:~/jfranzoy/tmp> /export/home/local/gdb-7.1/bin/gdb d GNU gdb (GDB) 7.1 Copyright (C) 2010 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "i386-pc-solaris2.10". For bug reporting instructions, please see: <http://www.gnu.org/software/gdb/bugs/>... Reading symbols from /export/home/bcpp/jfranzoy/tmp/d...(no debugging symbols found)...done. = = = I put breakpoints in every user defined function of function member = and in all __static_initialization_and_destruction_0. In every breakpoint = the call stack backtrace and the disassembly of the function is printed = (gdb) b a.cpp:__static_initialization_and_destruction_0 No symbol table is loaded. Use the "file" command. Make breakpoint pending on future shared library load? (y or [n]) Breakpoint 1 (a.cpp:__static_initialization_and_destruction_0) pending. (gdb) commands Type commands for when breakpoint 1 is hit, one per line. End with a line saying just "end". >silent >bt >disassemble >cont >end (gdb) (gdb) b b.cpp:__static_initialization_and_destruction_0 No symbol table is loaded. Use the "file" command. Make breakpoint pending on future shared library load? (y or [n]) Breakpoint 2 (b.cpp:__static_initialization_and_destruction_0) pending. (gdb) commands Type commands for when breakpoint 2 is hit, one per line. End with a line saying just "end". >silent >bt >disassemble >cont >end (gdb) (gdb) b c.cpp:__static_initialization_and_destruction_0 No symbol table is loaded. Use the "file" command. Make breakpoint pending on future shared library load? (y or [n]) Breakpoint 3 (c.cpp:__static_initialization_and_destruction_0) pending. (gdb) commands Type commands for when breakpoint 3 is hit, one per line. End with a line saying just "end". >silent >bt >disassemble >cont >end (gdb) (gdb) b d.cpp:__static_initialization_and_destruction_0 No symbol table is loaded. Use the "file" command. Make breakpoint pending on future shared library load? (y or [n]) Breakpoint 4 (d.cpp:__static_initialization_and_destruction_0) pending. (gdb) s The program is not being run. (gdb) silent Undefined command: "silent". Try "help". (gdb) bt No stack. (gdb) disassemble No frame selected. (gdb) cont The program is not being run. (gdb) end This command cannot be used at the top level. (gdb) This command cannot be used at the top level. (gdb) b AAA::AAA y comCan't find member of namespace, class, struct, or union named "AAA::AAA" Hint: try 'AAA::AAA<TAB> or 'AAA::AAA<ESC-?> (Note leading single quote.) Make breakpoint pending on future shared library load? (y or [n]) Please answer y or [n]. Make breakpoint pending on future shared library load? (y or [n]) mands Please answer y or [n]. Make breakpoint pending on future shared library load? (y or [n]) silent bt disassemble cont end b AAA::get y comPlease answer y or [n]. Make breakpoint pending on future shared library load? (y or [n]) Please answer y or [n]. Make breakpoint pending on future shared library load? (y or [n]) Please answer y or [n]. Make breakpoint pending on future shared library load? (y or [n]) Please answer y or [n]. Make breakpoint pending on future shared library load? (y or [n]) Please answer y or [n]. Make breakpoint pending on future shared library load? (y or [n]) (gdb) b AAA::get Can't find member of namespace, class, struct, or union named "AAA::get" Hint: try 'AAA::get<TAB> or 'AAA::get<ESC-?> (Note leading single quote.) Make breakpoint pending on future shared library load? (y or [n]) Breakpoint 5 (AAA::get) pending. (gdb) commands Type commands for when breakpoint 5 is hit, one per line. End with a line saying just "end". >silent >bt >disassemble >cont >end (gdb) (gdb) b DDD::DDD Can't find member of namespace, class, struct, or union named "DDD::DDD" Hint: try 'DDD::DDD<TAB> or 'DDD::DDD<ESC-?> (Note leading single quote.) Make breakpoint pending on future shared library load? (y or [n]) y commBreakpoint 6 (DDD::DDD) pending. (gdb) commands Type commands for when breakpoint 6 is hit, one per line. End with a line saying just "end". >silent >bt >disassemble >cont >end (gdb) (gdb) b DDD::get Can't find member of namespace, class, struct, or union named "DDD::get" Hint: try 'DDD::get<TAB> or 'DDD::get<ESC-?> (Note leading single quote.) Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 7 (DDD::get) pending. (gdb) commands Type commands for when breakpoint 7 is hit, one per line. End with a line saying just "end". >silent >bt >disassemble >cont >end (gdb) (gdb) b bbb1 Function "bbb1" not defined. Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 8 (bbb1) pending. (gdb) commands Type commands for when breakpoint 8 is hit, one per line. End with a line saying just "end". >silent >bt >disassemble >cont >end (gdb) (gdb) b CCC:CCC No symbol table is loaded. Use the "file" command. Make breakpoint pending on future shared library load? (y or [n]) y Breakpoint 9 (CCC:CCC) pending. (gdb) commands Type commands for when breakpoint 9 is hit, one per line. End with a line saying just "end". >silent >bt >disassemble >cont >end (gdb) (gdb) b main Breakpoint 10 at 0x8050c5a (gdb) commands Type commands for when breakpoint 10 is hit, one per line. End with a line saying just "end". >silent >bt >disassemble >cont >end (gdb) = = = = Start running it = (gdb) r Starting program: /export/home/bcpp/jfranzoy/tmp/d [Thread debugging using libthread_db enabled] [New Thread 1 (LWP 1)] [Switching to Thread 1 (LWP 1)] = = = = 1st breakpoint fired in static initialization of c.cpp (c.so) = it initialize ios_base and create global CCC object defined in c.cpp = #0 __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at c.cpp:19 #1 0xfef70b80 in _GLOBAL__sub_I_c.cpp () at c.cpp:19 #2 0xfef70c5d in __do_global_ctors_aux () from /export/home/bcpp/jfranzoy/tmp/c.so #3 0xfef70c8a in _init () from /export/home/bcpp/jfranzoy/tmp/c.so #4 0xfefce37e in call_init () from /usr/lib/ld.so.1 #5 0xfefcd7d5 in setup () from /usr/lib/ld.so.1 #6 0xfefdba3e in _setup () from /usr/lib/ld.so.1 #7 0xfefc299c in _rt_boot () from /usr/lib/ld.so.1 #8 0x08047648 in ?? () #9 0x08047774 in ?? () Backtrace stopped: previous frame inner to this frame (corrupt stack?) Dump of assembler code for function __static_initialization_and_destruction_0: 0xfef70b06 <+0>: push %ebp 0xfef70b07 <+1>: mov %esp,%ebp 0xfef70b09 <+3>: push %ebx 0xfef70b0a <+4>: sub $0x14,%esp 0xfef70b0d <+7>: call 0xfef70ba2 0xfef70b12 <+12>: add $0x101b6,%ebx => 0xfef70b18 <+18>: cmpl $0x1,0x8(%ebp) 0xfef70b1c <+22>: jne 0xfef70b43 <__static_initialization_and_destruction_0+61> 0xfef70b1e <+24>: cmpl $0xffff,0xc(%ebp) 0xfef70b25 <+31>: jne 0xfef70b43 <__static_initialization_and_destruction_0+61> 0xfef70b27 <+33>: lea 0x161(%ebx),%eax 0xfef70b2d <+39>: mov %eax,(%esp) 0xfef70b30 <+42>: call 0xfef70974 <std::ios_base::Init::Init()@plt> 0xfef70b35 <+47>: mov 0x24(%ebx),%eax 0xfef70b3b <+53>: mov %eax,(%esp) 0xfef70b3e <+56>: call 0xfef70984 <CCC::CCC()@plt> 0xfef70b43 <+61>: cmpl $0x0,0x8(%ebp) 0xfef70b47 <+65>: jne 0xfef70b60 <__static_initialization_and_destruction_0+90> 0xfef70b49 <+67>: cmpl $0xffff,0xc(%ebp) 0xfef70b50 <+74>: jne 0xfef70b60 <__static_initialization_and_destruction_0+90> 0xfef70b52 <+76>: lea 0x161(%ebx),%eax 0xfef70b58 <+82>: mov %eax,(%esp) 0xfef70b5b <+85>: call 0xfef70994 <std::ios_base::Init::~Init()@plt> 0xfef70b60 <+90>: add $0x14,%esp 0xfef70b63 <+93>: pop %ebx 0xfef70b64 <+94>: pop %ebp 0xfef70b65 <+95>: ret End of assembler dump. = = = = 2nd breakpoint fired in static initialization of b.cpp = It can be seen in the stack trace that this initialization is called inside c.cpp (c.so) static initialization. = = It can be explained because CCC contructor calls bbb1() function = which is defined in b.cpp (b.so) = = b.cpp static initialization just initialize ios_base = #0 __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at b.cpp:9 #1 0xfef20e97 in _GLOBAL__sub_I_b.cpp () at b.cpp:9 #2 0xfef20f1d in __do_global_ctors_aux () from /export/home/bcpp/jfranzoy/tmp/b.so #3 0xfef20f4a in _init () from /export/home/bcpp/jfranzoy/tmp/b.so #4 0xfefce37e in call_init () from /usr/lib/ld.so.1 #5 0xfefce1cf in is_dep_init () from /usr/lib/ld.so.1 #6 0xfefdaa4b in elf_bndr () from /usr/lib/ld.so.1 #7 0xfefc2ab4 in elf_rtbndr () from /usr/lib/ld.so.1 #8 0xfef90018 in ?? () #9 0xfef70b43 in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at c.cpp:19 #10 0xfef70b80 in _GLOBAL__sub_I_c.cpp () at c.cpp:19 #11 0xfef70c5d in __do_global_ctors_aux () from /export/home/bcpp/jfranzoy/tmp/c.so #12 0xfef70c8a in _init () from /export/home/bcpp/jfranzoy/tmp/c.so #13 0xfefce37e in call_init () from /usr/lib/ld.so.1 #14 0xfefcd7d5 in setup () from /usr/lib/ld.so.1 #15 0xfefdba3e in _setup () from /usr/lib/ld.so.1 #16 0xfefc299c in _rt_boot () from /usr/lib/ld.so.1 #17 0x08047648 in ?? () #18 0x08047774 in ?? () Backtrace stopped: previous frame inner to this frame (corrupt stack?) Dump of assembler code for function __static_initialization_and_destruction_0: 0xfef20e2b <+0>: push %ebp 0xfef20e2c <+1>: mov %esp,%ebp ---Type <return> to continue, or q <return> to quit--- 0xfef20e2e <+3>: push %ebx 0xfef20e2f <+4>: sub $0x14,%esp 0xfef20e32 <+7>: call 0xfef20eb9 0xfef20e37 <+12>: add $0x10141,%ebx => 0xfef20e3d <+18>: cmpl $0x1,0x8(%ebp) 0xfef20e41 <+22>: jne 0xfef20e5a <__static_initialization_and_destruction_0+47> 0xfef20e43 <+24>: cmpl $0xffff,0xc(%ebp) 0xfef20e4a <+31>: jne 0xfef20e5a <__static_initialization_and_destruction_0+47> 0xfef20e4c <+33>: lea 0x228(%ebx),%eax 0xfef20e52 <+39>: mov %eax,(%esp) 0xfef20e55 <+42>: call 0xfef20be0 <std::ios_base::Init::Init()@plt> 0xfef20e5a <+47>: cmpl $0x0,0x8(%ebp) 0xfef20e5e <+51>: jne 0xfef20e77 <__static_initialization_and_destruction_0+76> 0xfef20e60 <+53>: cmpl $0xffff,0xc(%ebp) 0xfef20e67 <+60>: jne 0xfef20e77 <__static_initialization_and_destruction_0+76> 0xfef20e69 <+62>: lea 0x228(%ebx),%eax 0xfef20e6f <+68>: mov %eax,(%esp) 0xfef20e72 <+71>: call 0xfef20bf0 <std::ios_base::Init::~Init()@plt> 0xfef20e77 <+76>: add $0x14,%esp 0xfef20e7a <+79>: pop %ebx 0xfef20e7b <+80>: pop %ebp 0xfef20e7c <+81>: ret End of assembler dump. = = = = 3rd breakpoint fired in bbb1(). Called from CCC constructor inside c.cpp (c.so) static initialization = = b.cpp (b.so) static initialization is already finished. = = bbb1() has a static AAA object. It calls __cxa_guard_acquire and __cxa_guard_release in order to make = this static object initialization thread safe, as c++11 mandates (as far as I suppose). = #0 bbb1 (i=10) at b.cpp:6 #1 0xfef70bc5 in CCC (this=0xfef80e28) at c.cpp:15 #2 0xfef70b43 in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at c.cpp:19 #3 0xfef70b80 in _GLOBAL__sub_I_c.cpp () at c.cpp:19 #4 0xfef70c5d in __do_global_ctors_aux () from /export/home/bcpp/jfranzoy/tmp/c.so #5 0xfef70c8a in _init () from /export/home/bcpp/jfranzoy/tmp/c.so #6 0xfefce37e in call_init () from /usr/lib/ld.so.1 #7 0xfefcd7d5 in setup () from /usr/lib/ld.so.1 #8 0xfefdba3e in _setup () from /usr/lib/ld.so.1 #9 0xfefc299c in _rt_boot () from /usr/lib/ld.so.1 #10 0x08047648 in ?? () #11 0x08047774 in ?? () Backtrace stopped: previous frame inner to this frame (corrupt stack?) Dump of assembler code for function bbb1(int): 0xfef20d3c <+0>: push %ebp 0xfef20d3d <+1>: mov %esp,%ebp 0xfef20d3f <+3>: push %edi 0xfef20d40 <+4>: push %esi 0xfef20d41 <+5>: push %ebx 0xfef20d42 <+6>: sub $0x1c,%esp 0xfef20d45 <+9>: call 0xfef20eb9 0xfef20d4a <+14>: add $0x1022e,%ebx => 0xfef20d50 <+20>: lea -0x1000a(%ebx),%eax 0xfef20d56 <+26>: mov %eax,0x4(%esp) 0xfef20d5a <+30>: mov 0x24(%ebx),%eax 0xfef20d60 <+36>: mov %eax,(%esp) 0xfef20d63 <+39>: call 0xfef20b40 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)@plt> 0xfef20d68 <+44>: mov 0x8(%ebp),%edx 0xfef20d6b <+47>: mov %edx,0x4(%esp) 0xfef20d6f <+51>: mov %eax,(%esp) 0xfef20d72 <+54>: call 0xfef20b50 <std::basic_ostream<char, std::char_traits<char> >::operator<<(int)@plt> 0xfef20d77 <+59>: lea -0x10004(%ebx),%edx 0xfef20d7d <+65>: mov %edx,0x4(%esp) 0xfef20d81 <+69>: mov %eax,(%esp) 0xfef20d84 <+72>: call 0xfef20b40 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)@plt> 0xfef20d89 <+77>: mov 0x30(%ebx),%edx 0xfef20d8f <+83>: mov %edx,0x4(%esp) 0xfef20d93 <+87>: mov %eax,(%esp) 0xfef20d96 <+90>: call 0xfef20b60 <std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))@plt> 0xfef20d9b <+95>: lea 0x230(%ebx),%eax 0xfef20da1 <+101>: movzbl (%eax),%eax 0xfef20da4 <+104>: test %al,%al ---Type <return> to continue, or q <return> to quit--- 0xfef20da6 <+106>: jne 0xfef20df5 <bbb1(int)+185> 0xfef20da8 <+108>: lea 0x230(%ebx),%eax 0xfef20dae <+114>: mov %eax,(%esp) 0xfef20db1 <+117>: call 0xfef20b70 <__cxa_guard_acquire@plt> 0xfef20db6 <+122>: test %eax,%eax 0xfef20db8 <+124>: setne %al 0xfef20dbb <+127>: test %al,%al 0xfef20dbd <+129>: je 0xfef20df5 <bbb1(int)+185> 0xfef20dbf <+131>: mov $0x0,%edi 0xfef20dc4 <+136>: mov 0x8(%ebp),%eax 0xfef20dc7 <+139>: mov %eax,0x4(%esp) 0xfef20dcb <+143>: lea 0x238(%ebx),%eax 0xfef20dd1 <+149>: mov %eax,(%esp) 0xfef20dd4 <+152>: call 0xfef20b80 <AAA::AAA(int)@plt> 0xfef20dd9 <+157>: lea 0x230(%ebx),%eax 0xfef20ddf <+163>: mov %eax,(%esp) 0xfef20de2 <+166>: call 0xfef20b90 <__cxa_guard_release@plt> 0xfef20de7 <+171>: lea -0x10262(%ebx),%eax 0xfef20ded <+177>: mov %eax,(%esp) 0xfef20df0 <+180>: call 0xfef20ba0 <atexit@plt> 0xfef20df5 <+185>: lea 0x238(%ebx),%eax 0xfef20dfb <+191>: mov %eax,(%esp) 0xfef20dfe <+194>: call 0xfef20bb0 <AAA::get() const@plt> 0xfef20e03 <+199>: add $0x1c,%esp 0xfef20e06 <+202>: pop %ebx 0xfef20e07 <+203>: pop %esi 0xfef20e08 <+204>: pop %edi 0xfef20e09 <+205>: pop %ebp 0xfef20e0a <+206>: ret 0xfef20e0b <+207>: mov %eax,%esi 0xfef20e0d <+209>: mov %edi,%eax 0xfef20e0f <+211>: test %al,%al 0xfef20e11 <+213>: jne 0xfef20e21 <bbb1(int)+229> 0xfef20e13 <+215>: lea 0x230(%ebx),%eax 0xfef20e19 <+221>: mov %eax,(%esp) 0xfef20e1c <+224>: call 0xfef20bc0 <__cxa_guard_abort@plt> 0xfef20e21 <+229>: mov %esi,%eax 0xfef20e23 <+231>: mov %eax,(%esp) 0xfef20e26 <+234>: call 0xfef20bd0 <_Unwind_Resume@plt> End of assembler dump. bbb1(10) = = = = 4th breakpoint fired in static initialization of a.cpp ??? Fired from CCC constructor inside c.cpp (c.so) static initialization = = This is THE mistery from my ignorant point of view. = Why is a.cpp static initialization called inside CCC ctor? = = a.cpp (a.so) static initialization may be called because bbb1 calls AAA ctor. = But bbb1 isn't in call stack backtrace. Some gcc, ld or ld.so magic?? = May be that gdb is not showing the exact call stack? = = a.cpp static initialization creates a global DDD object whose contructor calls bbb1() again = #0 __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at a.cpp:25 #1 0xfef41026 in _GLOBAL__sub_I_a.cpp () at a.cpp:25 #2 0xfef4107d in __do_global_ctors_aux () from /export/home/bcpp/jfranzoy/tmp/a.so #3 0xfef410aa in _init () from /export/home/bcpp/jfranzoy/tmp/a.so #4 0xfefce37e in call_init () from /usr/lib/ld.so.1 #5 0xfefce1cf in is_dep_init () from /usr/lib/ld.so.1 #6 0xfefdaa4b in elf_bndr () from /usr/lib/ld.so.1 #7 0xfefc2ab4 in elf_rtbndr () from /usr/lib/ld.so.1 #8 0xfef90980 in ?? () #9 0xfef70bc5 in CCC (this=0xfef80e28) at c.cpp:15 #10 0xfef70b43 in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at c.cpp:19 #11 0xfef70b80 in _GLOBAL__sub_I_c.cpp () at c.cpp:19 #12 0xfef70c5d in __do_global_ctors_aux () from /export/home/bcpp/jfranzoy/tmp/c.so #13 0xfef70c8a in _init () from /export/home/bcpp/jfranzoy/tmp/c.so #14 0xfefce37e in call_init () from /usr/lib/ld.so.1 #15 0xfefcd7d5 in setup () from /usr/lib/ld.so.1 #16 0xfefdba3e in _setup () from /usr/lib/ld.so.1 #17 0xfefc299c in _rt_boot () from /usr/lib/ld.so.1 #18 0x08047648 in ?? () #19 0x08047774 in ?? () Backtrace stopped: previous frame inner to this frame (corrupt stack?) Dump of assembler code for function __static_initialization_and_destruction_0: 0xfef40fac <+0>: push %ebp 0xfef40fad <+1>: mov %esp,%ebp 0xfef40faf <+3>: push %ebx ---Type <return> to continue, or q <return> to quit--- 0xfef40fb0 <+4>: sub $0x14,%esp 0xfef40fb3 <+7>: call 0xfef41048 0xfef40fb8 <+12>: add $0x10154,%ebx => 0xfef40fbe <+18>: cmpl $0x1,0x8(%ebp) 0xfef40fc2 <+22>: jne 0xfef40fe9 <__static_initialization_and_destruction_0+61> 0xfef40fc4 <+24>: cmpl $0xffff,0xc(%ebp) 0xfef40fcb <+31>: jne 0xfef40fe9 <__static_initialization_and_destruction_0+61> 0xfef40fcd <+33>: lea 0x238(%ebx),%eax 0xfef40fd3 <+39>: mov %eax,(%esp) 0xfef40fd6 <+42>: call 0xfef40c84 <std::ios_base::Init::Init()@plt> 0xfef40fdb <+47>: mov 0x58(%ebx),%eax 0xfef40fe1 <+53>: mov %eax,(%esp) 0xfef40fe4 <+56>: call 0xfef40c94 <DDD::DDD()@plt> 0xfef40fe9 <+61>: cmpl $0x0,0x8(%ebp) 0xfef40fed <+65>: jne 0xfef41006 <__static_initialization_and_destruction_0+90> 0xfef40fef <+67>: cmpl $0xffff,0xc(%ebp) 0xfef40ff6 <+74>: jne 0xfef41006 <__static_initialization_and_destruction_0+90> 0xfef40ff8 <+76>: lea 0x238(%ebx),%eax 0xfef40ffe <+82>: mov %eax,(%esp) 0xfef41001 <+85>: call 0xfef40ca4 <std::ios_base::Init::~Init()@plt> 0xfef41006 <+90>: add $0x14,%esp 0xfef41009 <+93>: pop %ebx 0xfef4100a <+94>: pop %ebp 0xfef4100b <+95>: ret End of assembler dump. = = = = 5th breakpoint fired in bbb1. This is a reentrant call, which is not supported by gcc for static = variable initialization inside a function: it deadlocks = #0 bbb1 (i=10) at b.cpp:6 #1 0xfef40f35 in DDD (this=0xfef51340) at a.cpp:17 #2 0xfef40fe9 in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at a.cpp:25 #3 0xfef41026 in _GLOBAL__sub_I_a.cpp () at a.cpp:25 #4 0xfef4107d in __do_global_ctors_aux () from /export/home/bcpp/jfranzoy/tmp/a.so #5 0xfef410aa in _init () from /export/home/bcpp/jfranzoy/tmp/a.so #6 0xfefce37e in call_init () from /usr/lib/ld.so.1 #7 0xfefce1cf in is_dep_init () from /usr/lib/ld.so.1 #8 0xfefdaa4b in elf_bndr () from /usr/lib/ld.so.1 #9 0xfefc2ab4 in elf_rtbndr () from /usr/lib/ld.so.1 #10 0xfef90980 in ?? () #11 0xfef70bc5 in CCC (this=0xfef80e28) at c.cpp:15 #12 0xfef70b43 in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at c.cpp:19 #13 0xfef70b80 in _GLOBAL__sub_I_c.cpp () at c.cpp:19 #14 0xfef70c5d in __do_global_ctors_aux () from /export/home/bcpp/jfranzoy/tmp/c.so #15 0xfef70c8a in _init () from /export/home/bcpp/jfranzoy/tmp/c.so #16 0xfefce37e in call_init () from /usr/lib/ld.so.1 #17 0xfefcd7d5 in setup () from /usr/lib/ld.so.1 #18 0xfefdba3e in _setup () from /usr/lib/ld.so.1 #19 0xfefc299c in _rt_boot () from /usr/lib/ld.so.1 #20 0x08047648 in ?? () #21 0x08047774 in ?? () Backtrace stopped: previous frame inner to this frame (corrupt stack?) Dump of assembler code for function bbb1(int): 0xfef20d3c <+0>: push %ebp 0xfef20d3d <+1>: mov %esp,%ebp 0xfef20d3f <+3>: push %edi 0xfef20d40 <+4>: push %esi 0xfef20d41 <+5>: push %ebx 0xfef20d42 <+6>: sub $0x1c,%esp 0xfef20d45 <+9>: call 0xfef20eb9 0xfef20d4a <+14>: add $0x1022e,%ebx => 0xfef20d50 <+20>: lea -0x1000a(%ebx),%eax 0xfef20d56 <+26>: mov %eax,0x4(%esp) 0xfef20d5a <+30>: mov 0x24(%ebx),%eax 0xfef20d60 <+36>: mov %eax,(%esp) 0xfef20d63 <+39>: call 0xfef20b40 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)@plt> 0xfef20d68 <+44>: mov 0x8(%ebp),%edx 0xfef20d6b <+47>: mov %edx,0x4(%esp) 0xfef20d6f <+51>: mov %eax,(%esp) ---Type <return> to continue, or q <return> to quit--- 0xfef20d72 <+54>: call 0xfef20b50 <std::basic_ostream<char, std::char_traits<char> >::operator<<(int)@plt> 0xfef20d77 <+59>: lea -0x10004(%ebx),%edx 0xfef20d7d <+65>: mov %edx,0x4(%esp) 0xfef20d81 <+69>: mov %eax,(%esp) 0xfef20d84 <+72>: call 0xfef20b40 <std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)@plt> 0xfef20d89 <+77>: mov 0x30(%ebx),%edx 0xfef20d8f <+83>: mov %edx,0x4(%esp) 0xfef20d93 <+87>: mov %eax,(%esp) 0xfef20d96 <+90>: call 0xfef20b60 <std::basic_ostream<char, std::char_traits<char> >::operator<<(std::basic_ostream<char, std::char_traits<char> >& (*)(std::basic_ostream<char, std::char_traits<char> >&))@plt> 0xfef20d9b <+95>: lea 0x230(%ebx),%eax 0xfef20da1 <+101>: movzbl (%eax),%eax 0xfef20da4 <+104>: test %al,%al 0xfef20da6 <+106>: jne 0xfef20df5 <bbb1(int)+185> 0xfef20da8 <+108>: lea 0x230(%ebx),%eax 0xfef20dae <+114>: mov %eax,(%esp) 0xfef20db1 <+117>: call 0xfef20b70 <__cxa_guard_acquire@plt> 0xfef20db6 <+122>: test %eax,%eax 0xfef20db8 <+124>: setne %al 0xfef20dbb <+127>: test %al,%al 0xfef20dbd <+129>: je 0xfef20df5 <bbb1(int)+185> 0xfef20dbf <+131>: mov $0x0,%edi 0xfef20dc4 <+136>: mov 0x8(%ebp),%eax 0xfef20dc7 <+139>: mov %eax,0x4(%esp) 0xfef20dcb <+143>: lea 0x238(%ebx),%eax 0xfef20dd1 <+149>: mov %eax,(%esp) 0xfef20dd4 <+152>: call 0xfef20b80 <AAA::AAA(int)@plt> 0xfef20dd9 <+157>: lea 0x230(%ebx),%eax 0xfef20ddf <+163>: mov %eax,(%esp) 0xfef20de2 <+166>: call 0xfef20b90 <__cxa_guard_release@plt> 0xfef20de7 <+171>: lea -0x10262(%ebx),%eax 0xfef20ded <+177>: mov %eax,(%esp) 0xfef20df0 <+180>: call 0xfef20ba0 <atexit@plt> 0xfef20df5 <+185>: lea 0x238(%ebx),%eax 0xfef20dfb <+191>: mov %eax,(%esp) 0xfef20dfe <+194>: call 0xfef20bb0 <AAA::get() const@plt> 0xfef20e03 <+199>: add $0x1c,%esp 0xfef20e06 <+202>: pop %ebx 0xfef20e07 <+203>: pop %esi 0xfef20e08 <+204>: pop %edi 0xfef20e09 <+205>: pop %ebp 0xfef20e0a <+206>: ret 0xfef20e0b <+207>: mov %eax,%esi 0xfef20e0d <+209>: mov %edi,%eax 0xfef20e0f <+211>: test %al,%al 0xfef20e11 <+213>: jne 0xfef20e21 <bbb1(int)+229> 0xfef20e13 <+215>: lea 0x230(%ebx),%eax 0xfef20e19 <+221>: mov %eax,(%esp) 0xfef20e1c <+224>: call 0xfef20bc0 <__cxa_guard_abort@plt> 0xfef20e21 <+229>: mov %esi,%eax 0xfef20e23 <+231>: mov %eax,(%esp) 0xfef20e26 <+234>: call 0xfef20bd0 <_Unwind_Resume@plt> End of assembler dump. bbb1(10) = = = = program hangs here = = = = I stopped debugging using ctrl-c = ^C Program received signal SIGINT, Interrupt. 0xfece9019 in __lwp_park () from /lib/libc.so.1 = = = = A call stack backtrace shows the deadlock, but do not shows the reentrant call to bbb1 = (gdb) bt #0 0xfece9019 in __lwp_park () from /lib/libc.so.1 #1 0xfece365e in cond_sleep_queue () from /lib/libc.so.1 #2 0xfece3817 in cond_wait_queue () from /lib/libc.so.1 #3 0xfece3b94 in cond_wait_common () from /lib/libc.so.1 #4 0xfece3d02 in _cond_wait () from /lib/libc.so.1 #5 0xfece3d2d in cond_wait () from /lib/libc.so.1 #6 0xfece3d66 in pthread_cond_wait () from /lib/libc.so.1 #7 0xfeed2898 in __gthread_cond_wait (g=0xfef311a8) at /export/home/bcpp/mlevalle/work/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=0xfef311a8) at /export/home/bcpp/mlevalle/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=0xfef311a8) at /export/home/bcpp/mlevalle/work/build-gcc/out/i386-pc-solaris2.10/libstdc++-v3/include/ext/concurrence.h:377 #10 __cxa_guard_acquire (g=0xfef311a8) at ../../../../src/gcc-4.6.2/libstdc++-v3/libsupc++/guard.cc:289 #11 0xfef20db6 in bbb1 (i=10) at b.cpp:7 #12 0xfef40f35 in DDD (this=0xfef51340) at a.cpp:17 #13 0xfef40fe9 in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at a.cpp:25 #14 0xfef41026 in _GLOBAL__sub_I_a.cpp () at a.cpp:25 #15 0xfef4107d in __do_global_ctors_aux () from /export/home/bcpp/jfranzoy/tmp/a.so #16 0xfef410aa in _init () from /export/home/bcpp/jfranzoy/tmp/a.so #17 0xfefce37e in call_init () from /usr/lib/ld.so.1 #18 0xfefce1cf in is_dep_init () from /usr/lib/ld.so.1 #19 0xfefdaa4b in elf_bndr () from /usr/lib/ld.so.1 #20 0xfefc2ab4 in elf_rtbndr () from /usr/lib/ld.so.1 #21 0xfef90980 in ?? () #22 0xfef70bc5 in CCC (this=0xfef80e28) at c.cpp:15 #23 0xfef70b43 in __static_initialization_and_destruction_0 (__initialize_p=1, __priority=65535) at c.cpp:19 #24 0xfef70b80 in _GLOBAL__sub_I_c.cpp () at c.cpp:19 #25 0xfef70c5d in __do_global_ctors_aux () from /export/home/bcpp/jfranzoy/tmp/c.so #26 0xfef70c8a in _init () from /export/home/bcpp/jfranzoy/tmp/c.so #27 0xfefce37e in call_init () from /usr/lib/ld.so.1 #28 0xfefcd7d5 in setup () from /usr/lib/ld.so.1 #29 0xfefdba3e in _setup () from /usr/lib/ld.so.1 #30 0xfefc299c in _rt_boot () from /usr/lib/ld.so.1 #31 0x08047648 in ?? () #32 0x08047774 in ?? () = = = = there is two threads = Backtrace stopped: previous frame inner to this frame (corrupt stack?) (gdb) info threads * 2 Thread 1 0xfece9019 in __lwp_park () from /lib/libc.so.1 1 LWP 1 0xfece9019 in __lwp_park () from /lib/libc.so.1 = = = = kill the program and stop the debugger = (gdb) kill Kill the program being debugged? (y or n) y (gdb) q solaris10:~/jfranzoy/tmp> Thans: Juan Carlos Franzoy