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.