This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

mt_allocator (rev 1.28) has static initilization problems?


I've been trying to the (trunk) mt_allocator within the gcc-3.4.0
sources (in another email thread) for alignment reasons on SPARC, and
so far, I haven't had problems there.  However, on i686-pc-linux-gnu,
I've encountered problems with static initialization of the
mt_allocator's _S_options structure.

For example, using gdb on the following small program will reveal that
when _S_initialize() runs on line 12, _S_options' constructor appears
to have not been run.  (I don't have a lot of luck setting breakpoints
on such things, so I am not 100% positive.)

  #include <memory>
  
  std::allocator<int *> alloc;
  struct init
  {
    init()
    {
      // Here, alloc._S_options is not initialized, so the constructor
      // makes a broken allocator.
      alloc.allocate(1);
    }
  
  } ini;
  
  int
  main()
  {
    std::allocator<void *> alloc2;
  
    // Here, this _S_options is initialized.
    alloc2.allocate(1);
    
    return 0;
  }

My guess is that _S_options' static initialization is happening after
the initialization of "ini". :(

I found this after narrowing down a real world problem to the
following more realistic test case, which crashes on global
destruction due to what appears to be invalid pointers in the deque's
std::allocator<int*> (within the stack).

  #include <list>
  #include <stack>
  #include <string>
  
  // (a) Reverse the order of these lines and it works
  std::stack<int> st_stack;
  std::string st_note("A");  // (b) Initialize this empty and it works
  
  int
  main()
  {
    std::list<int> container;
  
    // (c) Remove this line and it works
    container.push_front(0);
  
    return 0;
  }

If I link this program against the non-debug libstdc++, it runs,
unless I also link it against other system libraries, such as librt,
libpthread, libnsl or libdl, in which case it crashes inside the
mt_allocator on global destruction.  If I link it just against the
debug libstdc++, it crashes in the same place.

Example gdb output from the run of the first program (linked against
either the normal or debug libstdc++):

Breakpoint 1, init (this=0x8055689) at test_hosed.cc:10
10          alloc.allocate(1);
(gdb) s
__gnu_cxx::__mt_alloc<int*>::allocate (this=0x8055688, __n=1) at
mt_allocator.h:278
278           if (!_S_init)
(gdb) p *this
$1 = {
  static _S_init = false, 
  static _S_options = {
    _M_max_bytes = 0, 
    _M_min_bin = 0, 
    _M_chunk_size = 0, 
    _M_max_threads = 0, 
    _M_freelist_headroom = 0, 
    _M_force_new = false
  }, 
  static _S_binmap = 0x0, 
  static _S_bin = 0x0, 
  static _S_bin_size = 1
}

Example gdb output from a run of the second program linked against the
debug libstdc++:

Program received signal SIGSEGV, Segmentation fault.
0x0804961d in __gnu_cxx::__mt_alloc<int*>::deallocate
(this=0xbffff5a0, __p=0x8061c68, __n=8) at mt_allocator.h:461
461               __block->_M_next = __bin._M_first[0];

(gdb) bt
#0  0x0804961d in __gnu_cxx::__mt_alloc<int*>::deallocate
(this=0xbffff5a0, __p=0x8061c68, __n=8) at mt_allocator.h:461
#1  0x08049565 in std::_Deque_base<int, std::allocator<int>
>::_M_deallocate_map (this=0x8061020, __p=0x8061c68, __n=8)
    at stl_deque.h:409
#2  0x080494d5 in ~_Deque_base (this=0x8061020) at stl_deque.h:426
#3  0x0804947f in ~deque (this=0x8061020) at stl_deque.h:703
#4  0x0804930b in ~stack (this=0x8061020) at test_crash.cc:6
#5  0x08048c0f in __static_initialization_and_destruction_0
(__initialize_p=0, __priority=65535) at test_crash.cc:6
#6  0x08048c4c in global destructors keyed to st_stack () at
test_crash.cc:14
#7  0x0804892b in __do_global_dtors_aux ()
#8  0x0805bacd in _fini ()
#9  0x40065e53 in exit () from /lib/libc.so.6
#10 0x40053155 in __libc_start_main () from /lib/libc.so.6
#11 0x080488e1 in _start ()

(gdb) p __bin
$1 = (const __gnu_cxx::__mt_alloc<int*>::_Bin_record &) @0x80689e8:
Cannot access memory at address 0x80689e8
        
-- 
------------------------------------------------------------------
Brad Spencer - spencer@infointeractive.com - "It's quite nice..."
Systems Architect | InfoInterActive Corp. | A Canadian AOL Company


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]