Opened 12 years ago
Closed 12 years ago
#5444 closed Bugs (invalid)
boost::pool<>::ordered_malloc() crash
Reported by: | 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
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
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:
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 ;-)