[C++-sig] Bug and patch for boost.python with enable_shared_from_this

Chad Austin chad at imvu.com
Mon Feb 11 02:14:45 CET 2008


Hi all,

A month ago or so we discovered a bug in Boost.Python that manifests when
using enable_shared_from_this.  Here is a test case that demonstrates the
bug:

#include <boost/python.hpp>
#include <boost/enable_shared_from_this.hpp>

using namespace boost;
using namespace boost::python;

class Test;
typedef shared_ptr<Test> TestPtr;

class Test : public enable_shared_from_this<Test> {
public:
    static TestPtr construct() {
        return TestPtr(new Test);
    }

    void act() {
        TestPtr kungFuDeathGrip(shared_from_this());
    }

    void take(TestPtr t) {
    }
};

void Export_test() {
    class_<Test, TestPtr, noncopyable>("Test")
        .def("construct", &Test::construct)
        .staticmethod("construct")

        .def("act", &Test::act)
        .def("take", &Test::take)
        ;
}

And here is the Python:

        x = Test.construct()
        x.take(x)
        x.act()

The bug (as I understand it) is that the shared_ptr_from_python converter
creates a new shared_ptr for the Test instance to pass it into C++.  This
new shared_ptr has a nop deleter, except that it keeps the Python object
alive as long as the new shared_ptr is alive.  The problem here is that
creating a shared_ptr to an object of type T when T is
enable_shared_from_this<T> resets the weak pointer inside of
enable_shared_from_this<T>.  (See shared_ptr's constructors for the details
of the implementation.)  A fix that passes the test above and has worked for
us is to change shared_ptr's constructor to accept a
dont_enable_shared_from_this argument and pass that in from the
shared_ptr_from_python converter.  The patch is attached (against boost 1.33,
but the bug didn't look fixed in 1.34 either).

Cheers,
Chad

p.s. I have seen other people with this problem as well.  Googling for
bad_weak_ptr turns up several results.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20080210/cfebee7c/attachment.htm>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: enable_shared_from_this_boost_python.patch
Type: application/octet-stream
Size: 1285 bytes
Desc: not available
URL: <http://mail.python.org/pipermail/cplusplus-sig/attachments/20080210/cfebee7c/attachment.obj>


More information about the Cplusplus-sig mailing list