Opened 12 years ago

Closed 12 years ago

#5444 closed Bugs (invalid)

boost::pool<>::ordered_malloc() crash

Reported by: philippeb8@… Owned by: Chris Newbold
Milestone: To Be Determined Component: pool
Version: Boost 1.43.0 Severity: Problem
Keywords: Cc:

Description

Greetings,

I have a segmentation fault detected in Cygwin triggered by a call to boost::pool::ordered_malloc(). The test application can be found in the Shifted Pointer library of the Sandbox: $ svn co http://svn.boost.org/svn/boost/sandbox/shifted_ptr $ cd shifted_ptr/libs/smart_ptr/example $ make shifted_ptr_test3

Gives the following backtrace: #0 0x0040cd65 in boost::simple_segregated_storage<unsigned int>::try_malloc_n

(start=@0x22c4c8, n=14, partition_size=4) at /usr/include/boost/pool/simple_segregated_storage.hpp:234

#1 0x0040ce71 in boost::simple_segregated_storage<unsigned int>::malloc_n (

this=0x426020, n=15, partition_size=4) at /usr/include/boost/pool/simple_segregated_storage.hpp:256

#2 0x0040d168 in boost::pool<boost::default_user_allocator_new_delete>::ordered_malloc (this=0x426020, n=60) at /usr/include/boost/pool/pool.hpp:511 #3 0x0040f4a8 in boost::detail::sh::pool::allocate (this=0x426020, s=60)

at ../../../boost/detail/sh_owned_base_nt.hpp:122

#4 0x0040f88d in boost::detail::sh::shifted<node>::operator new (s=60)

at ../../../boost/detail/sh_owned_base_nt.hpp:262

#5 0x00402607 in list::insert (this=0x22c648) at shifted_ptr_test3.cpp:58 #6 0x00401569 in test_shifted_ptr::test_method (this=0x22c6e7)

at shifted_ptr_test3.cpp:96

#7 0x00401972 in test_shifted_ptr_invoker () at shifted_ptr_test3.cpp:82 #8 0x00411181 in boost::unit_test::ut_detail::invoker<boost::unit_test::ut_detail::unused>::invoke<void (*)()> (this=0x22c727, f=@0x64d9b4)

at /usr/include/boost/test/utils/callback.hpp:56

#9 0x0041107f in boost::unit_test::ut_detail::callback0_impl_t<boost::unit_test::ut_detail::unused, void (*)()>::invoke (this=0x64d9b0)

at /usr/include/boost/test/utils/callback.hpp:89

#10 0x638181e6 in cygboost_unit_test_framework-mt-1_43!_ZN5boost9unit_test14unit_test_mainEPFbvEiPPc ()

from /usr/bin/cygboost_unit_test_framework-mt-1_43.dll

#11 0x63808224 in cygboost_unit_test_framework-mt-1_43!_ZN5boost17execution_monitor13catch_signalsERKNS_9unit_test9callback0IiEE ()

from /usr/bin/cygboost_unit_test_framework-mt-1_43.dll

#12 0x638082a5 in cygboost_unit_test_framework-mt-1_43!_ZN5boost17execution_monitor7executeERKNS_9unit_test9callback0IiEE ()

from /usr/bin/cygboost_unit_test_framework-mt-1_43.dll

#13 0x638182fd in cygboost_unit_test_framework-mt-1_43!_ZN5boost9unit_test19unit_test_monitor_t21execute_and_translateERKNS0_9test_caseE ()

from /usr/bin/cygboost_unit_test_framework-mt-1_43.dll

#14 0x63834183 in cygboost_unit_test_framework-mt-1_43!_ZN5boost9unit_test14framework_impl5visitERKNS0_9test_caseE ()

from /usr/bin/cygboost_unit_test_framework-mt-1_43.dll

#15 0x63822285 in cygboost_unit_test_framework-mt-1_43!_ZN5boost9unit_test18traverse_test_treeERKNS0_10test_suiteERNS0_17test_tree_visitorE ()

from /usr/bin/cygboost_unit_test_framework-mt-1_43.dll

#16 0x6380b02e in cygboost_unit_test_framework-mt-1_43!_ZN5boost9unit_test9framework3runEmb () from /usr/bin/cygboost_unit_test_framework-mt-1_43.dll #17 0x63816b79 in cygboost_unit_test_framework-mt-1_43!_ZN5boost9unit_test14unit_test_mainEPFbvEiPPc ()

from /usr/bin/cygboost_unit_test_framework-mt-1_43.dll

#18 0x004019a6 in main (argc=1, argv=0x64a608)

at /usr/include/boost/test/unit_test.hpp:59

Thanks, -Phil

Change History (1)

comment:1 by John Maddock, 12 years ago

Resolution: invalid
Status: newclosed

I can reproduce on MSVC, but this seems to be a bug in shifted_ptr:

The order of operations on pool is:

create pool of block size 1.

Allocate 60 blocks

Allocate 60 blocks

Deallocate 60 blocks

Corruption of pools internal free list occures here >>>>>

Deallocate 60 blocks.

I set a memory breakpoint on the corrupted pool, and shifted pointer is changing the value 4 bytes into the already freed memory, with call stack:

scrap.exe!boost::detail::sp_counted_base::release() Line 100 + 0xd bytes C++ scrap.exe!boost::detail::sh::shifted_ptr_common<node>::~shifted_ptr_common<node>() Line 67 C++ scrap.exe!boost::detail::sh::shifted_ptr_base<node>::~shifted_ptr_base<node>() + 0x2b bytes C++ scrap.exe!boost::detail::sh::shifted_ptr<node>::~shifted_ptr<node>() Line 362 + 0xf bytes C++ scrap.exe!node::~node() Line 39 + 0x1a bytes C++ scrap.exe!boost::detail::sh::shifted<node>::~shifted<node>() Line 224 + 0xf bytes C++

scrap.exe!boost::detail::sh::shifted<node>::`scalar deleting destructor'() + 0x2b bytes C++

scrap.exe!boost::detail::sh::set::release() Line 99 + 0x39 bytes C++ scrap.exe!boost::detail::sh::shifted_ptr<node>::release(bool d) Line 375 + 0xb bytes C++ scrap.exe!boost::detail::sh::shifted_ptr<node>::reset() Line 357 C++ scrap.exe!list::clear() Line 53 C++ scrap.exe!test_shifted_ptr::test_method() Line 99 C++ scrap.exe!test_shifted_ptr_invoker() Line 82 + 0x26 bytes C++ scrap.exe!boost::unit_test::ut_detail::invoker<boost::unit_test::ut_detail::unused>::invoke<void (cdecl*)(void)>(void (void)* & f) Line 56 + 0x2c bytes C++ scrap.exe!boost::unit_test::ut_detail::callback0_impl_t<boost::unit_test::ut_detail::unused,void (__cdecl*)(void)>::invoke() Line 89 + 0x41 bytes C++

I also noted that:

1) If you're calling ordered_malloc then you should use ordered_free to free the memory. 2) Using pool(1) to allocate randomly sized blocks is likely to be very inefficient (worse than malloc/free), it would be much better if each shifted<T> had it's own pool for sizeof(T) chunks, and could therefore allocate 1 chunk at a time using the unordered pool interfaces (malloc and free) as this would be much more efficient. 3) owned_base has a static pool instance - this is not thread safe - which is to say pool is not safe for calling from mutiple threads. You could use singleton_pool<>::malloc/free instead of storing a static pool instance, and this would then be thread safe.

HTH, John.

PS closing down, please reopen if you really think it's a pool bug, but a test case involving just pool would be nice ;-)

Note: See TracTickets for help on using tickets.