Opened 14 years ago

Closed 13 years ago

#2869 closed Bugs (duplicate)

pool_allocator interferes with multi-layer instantiations

Reported by: ta0kira@… Owned by: Chris Newbold
Milestone: Boost 1.39.0 Component: pool
Version: Boost Development Trunk Severity: Problem
Keywords: Cc:

Description

Using pool_allocator with multiple layers of data causes misordered construction/destruction.

Test 1

In the example below, the problem is with construction. I was trying to reproduce a problem with destruction of static STL containers; however, the construction problem is the one that surfaced.

#include <vector>
#include <boost/pool/pool_alloc.hpp>

#include <stdio.h>


template <class Type>
struct container_spec
{
	typedef std::vector <Type, boost::pool_allocator <Type> > type;
};


typedef container_spec <int> ::type int_vector;
typedef container_spec <int_vector> ::type int_array;


int main()
{
	int_array array_of_int;

	for (int I = 0; I < 10; I++)
	{
	array_of_int.push_back( int_vector() );

	for (int J = 0; J < 10; J++)
	array_of_int[I].push_back(I * J);
	}

	fprintf(stderr, "vectors filled\n"); //<-- never seen
	fflush(stderr);
}

gdb backtrace is as follows:

Starting program: [...]/a.out

Program received signal SIGSEGV, Segmentation fault.
0x00000000004021aa in boost::simple_segregated_storage<unsigned long>::segregate (block=0x608330, sz=0, partition_sz=8, end=0x608338)
    at ./boost/pool/simple_segregated_storage.hpp:207
207         nextof(iter) = old;

(gdb) bt

#0  0x00000000004021aa in boost::simple_segregated_storage<unsigned long>::segregate (block=0x608330, sz=0, partition_sz=8, end=0x608338)
    at ./boost/pool/simple_segregated_storage.hpp:207
#1  0x0000000000402218 in boost::simple_segregated_storage<unsigned long>::add_block (this=0x607568, block=0x608330, nsz=0,
    npartition_sz=8) at ./boost/pool/simple_segregated_storage.hpp:72
#2  0x0000000000402444 in boost::simple_segregated_storage<unsigned long>::add_ordered_block (this=0x607568, block=0x608330, nsz=0,
    npartition_sz=8) at ./boost/pool/simple_segregated_storage.hpp:89
#3  0x00000000004024af in boost::simple_segregated_storage<unsigned long>::ordered_free_n (this=0x607568, chunks=0x608330, n=0,
    partition_size=8) at ./boost/pool/simple_segregated_storage.hpp:159
#4  0x0000000000402532 in boost::pool<boost::default_user_allocator_new_delete>::ordered_free (this=0x607568, chunks=0x608330, n=0)
    at ./boost/pool/pool.hpp:270
#5  0x0000000000402951 in boost::singleton_pool<boost::pool_allocator_tag, 4u, boost::default_user_allocator_new_delete, boost::details::pool::pthread_mutex, 32u>::ordered_free (ptr=0x608330, n=0) at ./boost/pool/singleton_pool.hpp:101
#6  0x0000000000402979 in boost::pool_allocator<int, boost::default_user_allocator_new_delete, boost::details::pool::pthread_mutex, 32u>::deallocate (ptr=0x608330, n=0) at ./boost/pool/pool_alloc.hpp:125
#7  0x00000000004029a4 in std::_Vector_base<int, boost::pool_allocator<int, boost::default_user_allocator_new_delete, boost::details::pool::pthread_mutex, 32u> >::_M_deallocate (this=0x608010, __p=0x608330, __n=0) at /usr/include/c++/4.2/bits/stl_vector.h:134
#8  0x0000000000404400 in std::vector<int, boost::pool_allocator<int, boost::default_user_allocator_new_delete, boost::details::pool::pthread_mutex, 32u> >::_M_insert_aux (this=0x608010, __position={_M_current = 0x608330}, __x=@0x7fff5b23c7a0)
    at /usr/include/c++/4.2/bits/vector.tcc:295
#9  0x000000000040449d in std::vector<int, boost::pool_allocator<int, boost::default_user_allocator_new_delete, boost::details::pool::pthread_mutex, 32u> >::push_back (this=0x608010, __x=@0x7fff5b23c7a0) at /usr/include/c++/4.2/bits/stl_vector.h:605
#10 0x0000000000401313 in main () at test.cpp:27

Test 2

The code below results in destruction errors, but not construction errors.

#include <vector>
#include <boost/pool/pool_alloc.hpp>

#include <stdio.h>


template <class Type>
struct container_spec
{
	typedef std::vector <Type, boost::pool_allocator <Type> > type;
};


typedef container_spec <int> ::type int_vector;
typedef container_spec <int_vector> ::type int_array;


int main()
{
	int_array array_of_int;

	array_of_int.push_back( int_vector() );

	fprintf(stderr, "vector added\n"); //<-- shows up
	fflush(stderr);
}

gdb backtrace is as follows:

Starting program: [...]/a.out
vector added

Program received signal SIGSEGV, Segmentation fault.
0x000000000040210a in boost::simple_segregated_storage<unsigned long>::segregate (block=0x607330, sz=0, partition_sz=8, end=0x607338)
    at ./boost/pool/simple_segregated_storage.hpp:207
207         nextof(iter) = old;

(gdb) bt

#0  0x000000000040210a in boost::simple_segregated_storage<unsigned long>::segregate (block=0x607330, sz=0, partition_sz=8, end=0x607338)
    at ./boost/pool/simple_segregated_storage.hpp:207
#1  0x00000000004023cf in boost::simple_segregated_storage<unsigned long>::add_ordered_block (this=0x606e48, block=0x607330, nsz=0,
    npartition_sz=8) at ./boost/pool/simple_segregated_storage.hpp:91
#2  0x000000000040240f in boost::simple_segregated_storage<unsigned long>::ordered_free_n (this=0x606e48, chunks=0x607330, n=0,
    partition_size=8) at ./boost/pool/simple_segregated_storage.hpp:159
#3  0x0000000000402492 in boost::pool<boost::default_user_allocator_new_delete>::ordered_free (this=0x606e48, chunks=0x607330, n=0)
    at ./boost/pool/pool.hpp:270
#4  0x00000000004028b1 in boost::singleton_pool<boost::pool_allocator_tag, 4u, boost::default_user_allocator_new_delete, boost::details::pool::pthread_mutex, 32u>::ordered_free (ptr=0x607330, n=0) at ./boost/pool/singleton_pool.hpp:101
#5  0x00000000004028d9 in boost::pool_allocator<int, boost::default_user_allocator_new_delete, boost::details::pool::pthread_mutex, 32u>::deallocate (ptr=0x607330, n=0) at ./boost/pool/pool_alloc.hpp:125
#6  0x0000000000402904 in std::_Vector_base<int, boost::pool_allocator<int, boost::default_user_allocator_new_delete, boost::details::pool::pthread_mutex, 32u> >::_M_deallocate (this=0x607010, __p=0x607330, __n=0) at /usr/include/c++/4.2/bits/stl_vector.h:134
#7  0x0000000000402944 in ~_Vector_base (this=0x607010) at /usr/include/c++/4.2/bits/stl_vector.h:120
#8  0x000000000040297f in ~vector (this=0x607010) at /usr/include/c++/4.2/bits/stl_vector.h:268
#9  0x0000000000402997 in boost::pool_allocator<std::vector<int, boost::pool_allocator<int, boost::default_user_allocator_new_delete, boost::details::pool::pthread_mutex, 32u> >, boost::default_user_allocator_new_delete, boost::details::pool::pthread_mutex, 32u>::destroy (
    ptr=0x607010) at ./boost/pool/pool_alloc.hpp:99
#10 0x00000000004029b5 in std::_Destroy<std::vector<int, boost::pool_allocator<int, boost::default_user_allocator_new_delete, boost::details::pool::pthread_mutex, 32u> >*, boost::pool_allocator<std::vector<int, boost::pool_allocator<int, boost::default_user_allocator_new_delete, boost::details::pool::pthread_mutex, 32u> >, boost::default_user_allocator_new_delete, boost::details::pool::pthread_mutex, 32u> > (
    __first=0x607010, __last=0x607028, __alloc={static next_size = <optimized out>}) at /usr/include/c++/4.2/bits/stl_construct.h:174
#11 0x0000000000402ad8 in ~vector (this=0x7fff34cb2200) at /usr/include/c++/4.2/bits/stl_vector.h:268
#12 0x000000000040130e in main () at test.cpp:25

In other circumstances of the same pattern these aren't a problem (too complex to post, but still a vector of vectors using pool_allocator.)

Partial source tree exported from http://svn.boost.org/svn/boost/trunk/boost/ Mon Mar 16 21:33:09 EDT 2009, didn't record the revision number.

Kevin P. Barry

> g++ -v

Using built-in specs.
Target: x86_64-linux-gnu
Configured with: ../src/configure -v --enable-languages=c,c++,fortran,objc,obj-c++,treelang --prefix=/usr --enable-shared --with-system-zlib
--libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --enable-nls --with-gxx-include-dir=/usr/include/c++/4.2 --program-suffix=-4.2
--enable-clocale=gnu --enable-libstdcxx-debug --enable-objc-gc --enable-mpfr --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu
--target=x86_64-linux-gnu
Thread model: posix
gcc version 4.2.4 (Ubuntu 4.2.4-1ubuntu3)

Change History (2)

comment:1 by Steven Watanabe, 14 years ago

Here's a reduced form of the problem:

#include <boost/pool/pool_alloc.hpp>

int main()
{
    boost::pool_allocator<int> alloc;
    int* p = alloc.allocate(0);
    alloc.deallocate(p, 0);
}

comment:2 by Steven Watanabe, 13 years ago

Resolution: duplicate
Status: newclosed

Duplicates #386.

Note: See TracTickets for help on using tickets.