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]

Re: mt_allocator: static DE-initialization order fiasco?


On Mon, Oct 11, 2004 at 02:14:07AM +0200, Paolo Carlini wrote:
> |Therefore, if you are getting into serious troubles using __mt_alloc
> directly, the same will happen if you just use std::allocator. Consider
> that mt_allocator is now the default in the build, therefore, if you
> just select the right policy via a typedef in include/ext/mt_allocator.h
> and rebuild the library you can very easily double check what I said.
> 
> Please, if you have a small testcase contribute it.

Ugh that wasn't easy :/.

I used "testsuite/ext/mt_allocator/deallocate_global-4.cc"
as a starting point.  However, I was forced to use more than
one shared library in order to enforce the deinitialization
fiasco to actually happen.

With the attached files, which I attached one by one so that
you can already see them without first saving the tar ball
first, you should be able to reproduce the following.
I also attached everything together as test.tar.bz2 for your
convenience.

$ make
g++-cvs-4.0 -I. -g -shared -o libfoo.so foo.cc memblk.cc
g++-cvs-4.0 -I. -g -shared -o libglobal1.so global1.cc
g++-cvs-4.0 -I. -g -shared -o libglobal2.so global2.cc
g++-cvs-4.0 -I. -g -L. -Wl,-rpath,`pwd` -lglobal1 -lfoo -lglobal2

$ ./a.out
Calling: operator new(258) = 0x804a008
Calling: operator new(100) = 0x804a110
Calling: operator new(4) = 0x804a178
Calling: operator new(4) = 0x804a188
Calling: operator new(4) = 0x804a198
Calling: operator new(4) = 0x804a1a8
Calling: operator new(4) = 0x804a1b8
Calling: operator new(4080) = 0x804a1c8
Calling: operator new(8) = 0x804b1c0
Calling: operator new(258) = 0x804b1d0
Calling: operator new(40) = 0x804b2d8
Calling: operator new(4) = 0x804b308
Calling: operator new(4) = 0x804b318
Calling: operator new(4) = 0x804b328
Calling: operator new(4) = 0x804b338
Calling: operator new(4) = 0x804b348
Calling: operator new(4080) = 0x804b358
Calling: operator new(8) = 0x804c350
Starting destruction.
Destructing object "global1.cc" which is using memory at 0x804b3bc.
This memory belongs to a memory block starting at 0x804b358 with size 4080.
Calling: delete 0x804b308
Calling: delete 0x804b318
Calling: delete 0x804b358  <=== range: [0x804b358 - 0x804c348)
Calling: delete 0x804c350
Calling: delete 0x804b328
Calling: delete 0x804b338
Calling: delete 0x804b348
Calling: delete 0x804b2d8
Calling: delete 0x804b1d0
Destructing object "foo.cc" which is using memory at 0x804b394.
Calling: operator new(4080) = 0x804b1d0
Calling: operator new(8) = 0x804c1c8
terminate called after throwing an instance of 'std::runtime_error'
  what():  Allocation is already freed
Aborted

As you can see, the object "foo.cc" is using memory at 0x804b394
that falls in the range [0x804b358 - 0x804c348) of a memory block
that already freed.

-- 
Carlo Wood <carlo@alinoe.com>

Attachment: Makefile
Description: Text document

Attachment: string_t.h
Description: Text document

Attachment: memblk.h
Description: Text document

Attachment: Global.h
Description: Text document

Attachment: memblk.cc
Description: Text document

Attachment: global1.cc
Description: Text document

Attachment: global2.cc
Description: Text document

Attachment: foo.cc
Description: Text document

Attachment: test.tar.bz2
Description: BZip2 compressed data


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