This is the mail archive of the
libstdc++@gcc.gnu.org
mailing list for the libstdc++ project.
mt_allocator (rev 1.28) has static initilization problems?
- From: Brad Spencer <spencer at infointeractive dot com>
- To: libstdc++ at gcc dot gnu dot org
- Date: Thu, 6 May 2004 12:11:14 -0300
- Subject: 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