Hi all,<br><br>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:<br><br>
<div style="margin-left: 40px;">#include <boost/python.hpp><br>
#include <boost/enable_shared_from_this.hpp><br>
<br>
using namespace boost;<br>
using namespace boost::python;<br>
<br>
class Test;<br>
typedef shared_ptr<Test> TestPtr;<br>
<br>
class Test : public enable_shared_from_this<Test> {<br>
public:<br>
static TestPtr construct() {<br>
return TestPtr(new Test);<br>
}<br>
<br>
void act() {<br>
TestPtr kungFuDeathGrip(shared_from_this());<br>
}<br>
<br>
void take(TestPtr t) {<br>
}<br>
};<br>
<br>
void Export_test() {<br>
class_<Test, TestPtr, noncopyable>("Test")<br>
.def("construct", &Test::construct)<br>
.staticmethod("construct")<br>
<br>
.def("act", &Test::act)<br>
.def("take", &Test::take)<br>
;<br>
}<br>
</div>
<br>
And here is the Python:<br>
<br>
x = Test.construct()<br>
x.take(x)<br>
x.act()<br>
<br>
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).<br>
<br>Cheers,<br>Chad<br><br>p.s. I have seen other people with this problem as well. Googling for bad_weak_ptr turns up several results.<br>