Opened 9 years ago
Closed 9 years ago
#9535 closed Bugs (fixed)
Missing exception safety might result in crash
| Reported by: | anonymous | Owned by: | viboes |
|---|---|---|---|
| Milestone: | Boost 1.56.0 | Component: | thread |
| Version: | Boost 1.55.0 | Severity: | Problem |
| Keywords: | Cc: |
Description
As I was curious as to how boost::wait_for_any is implemented, and I think I found a little flaw in the future_waiter class in boost/thread/future.hpp ( which the documentation incorrectly lists as <boost/thread/futures.hpp> ):
The future_waiter class registers it's condition variable in the add function
template<typename F>
void add(F& f)
{
if(f.future_)
{
futures.push_back(registered_waiter(f.future_,f.future_->register_external_waiter(cv),future_count));
}
++future_count;
}
and unregisters it in the destructor
~future_waiter()
{
for(count_type i=0;i<futures.size();++i)
{
futures[i].future_->remove_external_waiter(futures[i].wait_iterator);
}
}
However, if the program encounters an out-of-memory condition during it's call to push_back in add(), the registered_waiter is not stored in the vector und thus is not unregistered in the destructor, so as soon as the future readies up, it calls notify_all on a dangling pointer, resulting in a crash. I was able to successfully construct this scenario by overloading operator new() using GCC on a unix-like OS.
I suggest adding a mechanism to unregister the waiter in case of an exception. Changing the add function to the following fixed it for me:
template<typename F>
void add(F& f)
{
if(f.future_)
{
registered_waiter waiter(f.future_,f.future_->register_external_waiter(cv),future_count);
try {
futures.push_back(waiter);
} catch(...) {f.future_->remove_external_waiter(waiter.wait_iterator); throw;}
}
++future_count;
}
As you see, I have just introduced a local variable and a try-catch block. There could be more elegant solutions, but this was the first one that came to mind.
Change History (4)
comment:1 by , 9 years ago
| Owner: | changed from to |
|---|---|
| Status: | new → assigned |
comment:2 by , 9 years ago
| Milestone: | To Be Determined → Boost 1.56.0 |
|---|
comment:3 by , 9 years ago
comment:4 by , 9 years ago
| Resolution: | → fixed |
|---|---|
| Status: | assigned → closed |

Thanks for catching this.