possible bug introduced in boost function

I have strong suspicions that the changes in boost::function made today introduce a serious bug in the lifetime management of the contained object. I don't have a simple test case to demonstrate it, but a rather complicated use of boost::function which contains shared_ptr in a boost::bind results in incorrect refcount which leads to a crash. Reverting to revision 48607 makes the shared_ptr refcount correct. Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

On Fri, Sep 5, 2008 at 6:22 PM, Emil Dotchevski <emil@revergestudios.com> wrote:
I have strong suspicions that the changes in boost::function made today introduce a serious bug in the lifetime management of the contained object. I don't have a simple test case to demonstrate it, but a rather complicated use of boost::function which contains shared_ptr in a boost::bind results in incorrect refcount which leads to a crash.
Reverting to revision 48607 makes the shared_ptr refcount correct.
Here's a simple test case, I tried it with msvc 9: #include "boost/function.hpp" int instances=0; struct X { X() { ++instances; } X(X const &) { ++instances; } ~X() { --instances; } void operator()() { } }; boost::function<void()> f() { return X(); } int main( int argc, char const * argv[] ) { boost::function<void()> f2; f2=f(); assert(instances==1); } Emil Dotchevski Reverge Studios, Inc. http://www.revergestudios.com/reblog/index.php?n=ReCode

Emil Dotchevski wrote:
I have strong suspicions that the changes in boost::function made today introduce a serious bug in the lifetime management of the contained object. ... Reverting to revision 48607 makes the shared_ptr refcount correct.
Thank you, Emil! Douglas has fixed the issue just a few hours ago: http://svn.boost.org/trac/boost/changeset/48627 See also: http://svn.boost.org/trac/boost/ticket/1910#comment:6
Here's a simple test case, I tried it with msvc 9:
#include "boost/function.hpp"
int instances=0; struct X { X() { ++instances; } X(X const &) { ++instances; } ~X() { --instances; } void operator()() { } }; boost::function<void()> f() { return X(); }
int main( int argc, char const * argv[] ) { boost::function<void()> f2; f2=f(); assert(instances==1); }
I just tried your little test case. Before Doug's fix [48627], "instances" was -1 during the assert, now it's 1 again, as it should. :-) So now we have a boost::function::swap function that significantly outperforms std::swap<boost::function>, when swapping large functors. :-) Kind regards, Niels

Emil Dotchevski wrote:
I have strong suspicions that the changes in boost::function made today introduce a serious bug in the lifetime management of the contained object. I don't have a simple test case to demonstrate it, but a rather complicated use of boost::function which contains shared_ptr in a boost::bind results in incorrect refcount which leads to a crash.
Thanks for pointing this out! I'm surprised I'd never put such a test into the Boost.Function test suite before. Anyway, the error has been fixed and I've added such a test. - Doug

Douglas Gregor:
Thanks for pointing this out! I'm surprised I'd never put such a test into the Boost.Function test suite before. Anyway, the error has been fixed and I've added such a test.
Looking at http://svn.boost.org/trac/boost/changeset/48627 did you intend the large functor to be, well, large?

Peter Dimov wrote:
Douglas Gregor:
Thanks for pointing this out! I'm surprised I'd never put such a test into the Boost.Function test suite before. Anyway, the error has been fixed and I've added such a test.
Looking at
http://svn.boost.org/trac/boost/changeset/48627
did you intend the large functor to be, well, large? *Sigh*, yes. Thank you.
- Doug
participants (4)
-
Douglas Gregor
-
Emil Dotchevski
-
Niels Dekker - mail address until 2008-12-31
-
Peter Dimov