|
Boost Users : |
Subject: Re: [Boost-users] boost::interprocess segfault when calling pop on deque
From: OvermindDL1 (overminddl1_at_[hidden])
Date: 2010-07-29 21:16:26
On Tue, Jul 27, 2010 at 2:45 PM, Matthew Stump <mstump_at_[hidden]> wrote:
> I built a datastrucuture which I called BufferedQueue. Â It's
> essentially a double buffered queue but instead of two buffers I allow
> a user specified number of buffers. Â Each buffer is a struct which
> contains the managed_mapped_file for the particular buffer and a
> pointer to a boost::interprocess::deque. Â Each mapped file contains
> only 1 deque and the deque is used to store items pushed onto the
> queue by the user. Â I automatically handle rotation between the
> various buffers when the user calls push or pop.
>
> Specific problem:
> All of my functional unit tests pass without issue and I have 100%
> test coverage. Â When I run the multi-threaded unit tests I encounter a
> segfault, but not immediately. Â I have some tests which will spawn one
> thread which instantiates the datastrucutre and will push 100K items
> onto the queue (this will span multiple buffers). Â I spawn a second
> thread which also instantiates the datastrucutre and begin to pop
> items off of the queue. Â After about 40K items have been poped off of
> the queue I get a segfault when calling
> boost::interprocess::deque::pop_front(). Â It's always on the same
> line, and occurs when the segment manager is doing it's sanity checks
> while de-allocating the memory. Â Sometimes this occurs when it's the
> last item in the deque which is being poped, sometimes it's not; there
> is no detectable pattern. Â For my test I'm also using ints so I'm not
> pushing something onto the datastrucutre that isn't compatible with
> boost::interprocess.
>
> Any helpful ideas as to what may be the cause of my problem would be greatly appreciated.
>
> // Type declarations for the deque
> typedef boost::interprocess::managed_mapped_file           ManagedFile;
> typedef ManagedFile::segment_manager                 SegmentManager;
> typedef typename boost::interprocess::allocator<T, SegmentManager> Â TypeAllocator;
> typedef typename boost::interprocess::list<T, TypeAllocator> Â Â Â Â MMContainer;
>
> // instantiation of the deque
> queue = file.find_or_construct<MMContainer>(getBufferName(name, buffNum).c_str())(TypeAllocator(file.get_segment_manager()));
>
> // my pop method
> template<class T>
> void
> BufferedQueue<T>::pop()
> {
> Â Â checkBufferCount();
>
> Â Â {
> Â Â Â Â boost::interprocess::sharable_lock<Mutex> master_lock(*m_masterMutex);
> Â Â Â Â boost::interprocess::scoped_lock<typename Buffer<T>::Mutex> lock(*getReadBuffer().mutex);
>
> Â Â Â Â assert(getReadBuffer().queue);
> Â Â Â Â if (!isBufferEmpty<T>(getReadBuffer()))
> Â Â Â Â {
> Â Â Â Â Â Â assert(!getReadBuffer().queue->empty());
> Â Â Â Â Â Â getReadBuffer().queue->pop_front();
> Â Â Â Â Â Â return;
> Â Â Â Â }
> Â Â }
>
> Â Â rotate_reader();
> Â Â boost::interprocess::sharable_lock<Mutex> master_lock(*m_masterMutex);
> Â Â boost::interprocess::scoped_lock<typename Buffer<T>::Mutex> lock(*getReadBuffer().mutex);
> Â Â if (isBufferEmpty<T>(getReadBuffer()))
> Â Â Â Â throw Exception("called pop() on an empty buffer");
>
> Â Â assert(!getReadBuffer().queue->empty());
> Â Â getReadBuffer().queue->pop_front();
> }
>
> /libs2/external/boost/boost/interprocess/mem_algo/rbtree_best_fit.hpp:1244: void boost::interprocess::rbtree_best_fit<MutexFamily, VoidMutex, MemAlignment>::priv_deallocate(void*) [with MutexFamily = boost::interprocess::mutex_family, VoidPointer = boost::interprocess::offset_ptr<void>, unsigned int MemAlignment = 0u]: Assertion `priv_is_allocated_block(block)' failed.
>
> #0 Â 0x0094a410 in __kernel_vsyscall ()
> #1 Â 0x02850df0 in raise () from /lib/libc.so.6
> #2 Â 0x02852701 in abort () from /lib/libc.so.6
> #3 Â 0x0284a26b in __assert_fail () from /lib/libc.so.6
> #4 Â 0x0806ca9f in boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0u>::priv_deallocate (this=0xb5fcd004, addr=0xb5fcd0b8)
> Â Â at /libs2/external/boost/boost/interprocess/mem_algo/rbtree_best_fit.hpp:1244
> #5 Â 0x0807b00b in boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0u>::deallocate (this=0xb5fcd004, addr=0xb5fcd0b8)
> Â Â at /libs2/external/boost/boost/interprocess/mem_algo/rbtree_best_fit.hpp:1233
> #6 Â 0x0807b05f in boost::interprocess::segment_manager_base<boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0u> >::deallocate
> Â Â (this=0xb5fcd004, addr=0xb5fcd0b8) at /libs2/external/boost/boost/interprocess/segment_manager.hpp:217
> #7 Â 0x0807b5fe in boost::interprocess::allocator<boost::container::containers_detail::list_node<int, boost::interprocess::offset_ptr<void> >, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0u>, boost::interprocess::iset_index> >::deallocate (this=0xb5fcd0b0, ptr=...)
> Â Â at /libs2/external/boost/boost/interprocess/allocators/allocator.hpp:152
> #8 Â 0x0807b61c in boost::interprocess::allocator<boost::container::containers_detail::list_node<int, boost::interprocess::offset_ptr<void> >, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0u>, boost::interprocess::iset_index> >::deallocate_one (this=0xb5fcd0b0, p=...)
> Â Â at /libs2/external/boost/boost/interprocess/allocators/allocator.hpp:234
> #9 Â 0x0807b693 in boost::container::containers_detail::allocator_destroyer<boost::interprocess::allocator<boost::container::containers_detail::list_node<int, boost::interprocess::offset_ptr<void> >, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0u>, boost::interprocess::iset_index> > >::priv_deallocate (this=0x43511dc, p=...) at /libs2/external/boost/boost/interprocess/containers/container/detail/destroyers.hpp:133
> #10 0x0807b6ca in boost::container::containers_detail::allocator_destroyer<boost::interprocess::allocator<boost::container::containers_detail::list_node<int, boost::interprocess::offset_ptr<void> >, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0u>, boost::interprocess::iset_index> > >::operator() (this=0x43511dc, p=...) at /libs2/external/boost/boost/interprocess/containers/container/detail/destroyers.hpp:143
> #11 0x0807b786 in boost::intrusive::list_impl<boost::intrusive::listopt<boost::intrusive::detail::base_hook_traits<boost::container::containers_detail::list_node<int, boost::interprocess::offset_ptr<void> >, boost::intrusive::list_node_traits<boost::interprocess::offset_ptr<void> >, normal_link, boost::intrusive::default_tag, 1>, unsigned int, true> >::erase_and_dispose<boost::container::containers_detail::allocator_destroyer<boost::interprocess::allocator<boost::container::containers_detail::list_node<int, boost::interprocess::offset_ptr<void> >, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0u>, boost::interprocess::iset_index> > > > (
> Â Â this=0xb5fcd0b4, i=..., disposer=...) at /libs2/external/boost/boost/intrusive/list.hpp:649
> #12 0x0807b7ce in boost::intrusive::list_impl<boost::intrusive::listopt<boost::intrusive::detail::base_hook_traits<boost::container::containers_detail::list_node<int, boost::interprocess::offset_ptr<void> >, boost::intrusive::list_node_traits<boost::interprocess::offset_ptr<void> >, normal_link, boost::intrusive::default_tag, 1>, unsigned int, true> >::erase_and_dispose<boost::container::containers_detail::allocator_destroyer<boost::interprocess::allocator<boost::container::containers_detail::list_node<int, boost::interprocess::offset_ptr<void> >, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0u>, boost::interprocess::iset_index> > > > (
> Â Â this=0xb5fcd0b4, i=..., disposer=...) at /libs2/external/boost/boost/intrusive/list.hpp:656
> #13 0x0807b839 in boost::container::list<int, boost::interprocess::allocator<int, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0u>, boost::interprocess::iset_index> > >::erase (this=0xb5fcd0b0, p=...)
> Â Â at /libs2/external/boost/boost/interprocess/containers/container/list.hpp:930
> #14 0x0807b881 in boost::container::list<int, boost::interprocess::allocator<int, boost::interprocess::segment_manager<char, boost::interprocess::rbtree_best_fit<boost::interprocess::mutex_family, boost::interprocess::offset_ptr<void>, 0u>, boost::interprocess::iset_index> > >::pop_front (this=0xb5fcd0b0)
> Â Â at /libs2/external/boost/boost/interprocess/containers/container/list.hpp:623
> #15 0x0808a2e2 in Ovid::BufferedQueue<int>::pop (this=0x43512f0) at /ovid/server/shared/ovidserver-bufferedqueue.cpp:287
> #16 0x080557fb in reader_multithread_two_writer_single_reader_throughput () at test-ovidserver-bufferedqueue.cpp:389
> #17 0x07653832 in start_thread () from /lib/libpthread.so.0
> #18 0x028f9e0e in clone () from /lib/libc.so.6
It is best if you can supply a completely self-contained (using boost
of course) example that demonstrates the issue.
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net