Hi,
I have a small example program that crashes from time to time.
I would appreciate some help to understand why.
In function run() executed on the main thread I create a packaged_task (pt), put it in a queue (_q) and wait for it to get executed (fu.get()).
In another thread the tasks are executed when the queue _q is populated.
The task I'm running always throws/rethrows intentionally.
It results (from time to time) in an access violation when the unique_future, fu, is deleted.
See the stack trace at the bottom.
Anybody see any flaws in this design?
I have tried 1.47.0 and 1.48.0, MSVC 2005.
Here's the code.
*****************************************************
#include
#include
#include <sstream>
#include <iostream>
struct Exception
: public virtual std::exception
, public virtual boost::exception
{
};
struct TheException : public virtual Exception {};
void throwf()
{
try
{
BOOST_THROW_EXCEPTION(TheException());
}
catch (...)
{
boost::current_exception_diagnostic_information();
throw;
}
}
struct Test
{
Test()
{
_t.reset(new boost::thread(boost::bind(&Test::executor, this)));
}
~Test()
{
_t->join();
}
void executor()
{
for (;;)
{
boost::unique_lockboost::mutex lk(_mx);
while(_q.empty())
{
_cv.wait(lk);
}
boost::shared_ptr< boost::packaged_task<void> > pt = _q.front();
_q.pop_front();
lk.unlock();
(*pt)();
}
}
void run()
{
for (;;)
{
const int N = 20000;
for (int j = 0; j < N; ++j)
{
boost::shared_ptr< boost::packaged_task<void> > pt(new boost::packaged_task<void>(throwf));
boost::unique_future<void> fu = pt->get_future();
{
boost::unique_lockboost::mutex lk(_mx);
_q.push_back(pt);
pt.reset();
}
_cv.notify_one();
try
{
fu.get();
assert(false);
}
catch (const TheException& )
{
}
catch (const boost::exception& )
{
assert(false);
}
catch (...) {
assert(false);
}
}
std::cout << ".";
}
}
private:
boost::mutex _mx;
std::list< boost::shared_ptr< boost::packaged_task<void> > > _q;
boost::shared_ptrboost::thread _t;
boost::condition_variable_any _cv;
};
int main(int, char*)
{
Test test;
test.run();
}
*****************************************************
Here is the callstack, program terminated with access violation.
Unhandled exception at 0x0043196b in crasher.exe: 0xC0000005: Access violation reading location 0xdddddded.
crasher.exe!boost::exception_detail::refcount_ptrboost::exception_detail::error_info_container::release() Line 78 + 0x18 bytes C++
crasher.exe!boost::exception_detail::refcount_ptrboost::exception_detail::error_info_container::~refcount_ptrboost::exception_detail::error_info_container() Line 35 C++
crasher.exe!boost::exception::~exception() Line 278 + 0xb bytes C++
crasher.exe!boost::exception_detail::clone_impl<TheException>::`vbase destructor'() + 0x41 bytes C++
crasher.exe!boost::exception_detail::clone_impl<TheException>::`scalar deleting destructor'() + 0x2b bytes C++
crasher.exe!boost::checked_delete(const boost::exception_detail::clone_base * x=0x006f7d10) Line 34 + 0x35 bytes C++
crasher.exe!boost::detail::sp_counted_impl_p::dispose() Line 78 + 0xc bytes C++
crasher.exe!boost::detail::sp_counted_base::release() Line 102 + 0xf bytes C++
crasher.exe!boost::detail::shared_count::~shared_count() Line 309 C++
crasher.exe!boost::shared_ptr::~shared_ptr() + 0x2e bytes C++
crasher.exe!boost::exception_ptr::~exception_ptr() + 0x2b bytes C++
crasher.exe!boost::detail::future_object_base::~future_object_base() Line 106 + 0x9c bytes C++
crasher.exe!boost::detail::future_object<void>::~future_object<void>() + 0x2b bytes C++
crasher.exe!boost::detail::task_base<void>::~task_base<void>() + 0x2b bytes C++
crasher.exe!boost::detail::task_object::~task_object() + 0x2b bytes C++
crasher.exe!boost::detail::task_object::`scalar deleting destructor'() + 0x2b bytes C++
crasher.exe!boost::checked_delete >(boost::detail::task_object * x=0x006f7b10) Line 34 + 0x34 bytes C++
crasher.exe!boost::detail::sp_counted_impl_p >::dispose() Line 78 + 0xc bytes C++
crasher.exe!boost::detail::sp_counted_base::release() Line 102 + 0xf bytes C++
crasher.exe!boost::detail::shared_count::~shared_count() Line 309 C++
crasher.exe!boost::shared_ptr::~shared_ptr() + 0x2e bytes C++
crasher.exe!boost::unique_future<void>::~unique_future<void>() Line 644 + 0x2b bytes C++
crasher.exe!Test::run() Line 95 + 0xc bytes C++
crasher.exe!main(int __formal=1, int __formal=1) Line 112 C++
crasher.exe!__tmainCRTStartup() Line 597 + 0x19 bytes C
crasher.exe!mainCRTStartup() Line 414 C
kernel32.dll!7c817067()
[Frames below may be incorrect and/or missing, no symbols loaded for kernel32.dll]
________________________________
Please consider the environment before printing this e-mail.
The contents of this e-mail message (including any attachments) are confidential to and are intended to be conveyed for the use of the recipient to whom it is addressed only. If you receive this transmission in error, please notify the sender of this immediately and delete the message from your system. Any distribution, reproduction or use of this message by someone other than recipient is not authorized and may be unlawful.