I believe the following behaviour changes in 1.63 judging by the
ChangeLog, though unfortunately I can only test 1.60 vs 1.66 at the
moment. Using Enterprise Linux 7 with gcc 7.2.
Consider this module:
#include <boost/python.hpp>
#include <iostream>
#include <memory>
namespace bp = boost::python;
struct X
{
~X () { std::cout << "Bye bye" << std::endl; }
};
BOOST_PYTHON_MODULE (pymodule)
{
bp::class_<X, std::shared_ptr<X>> x_wrap ("X");
// Not needed in newer boost
bp::register_ptr_to_python<std::shared_ptr<X>> ();
auto x1 = std::make_shared<X> ();
auto x2 = bp::extract<std::shared_ptr<X>> (bp::object (x1)) ();
// On a newer boost: use counts are not the same
std::cout << x1.get () << ": "<< x1.use_count () << std::endl; // 2
std::cout << x2.get () << ": "<< x2.use_count () << std::endl; // 1 :(
}
For the older Boost, the reference counts are both two, but they are 2
and 1 respectively in the newer Boost. Is this expected? I wonder if
there's some cleverness involving x2 somehow pointing to a BP object
that in turn points to x1. Curiously X appears to only be destructed
once, so it doesn't look like UB.
Where it bites me is cleanup time. If I add the following to the end
of the module, I get a segfault:
static std::vector<std::shared_ptr<X>> v {x2};
Backtrace as follows:
#0 subtype_dealloc (self=0x7ffff7e24050) at Objects/typeobject.c:955
#1 0x00007fffef9dfb59 in xdecref<_object> (p=<optimized out>) at
./boost/python/refcount.hpp:38
#2 reset (this=0x6c1f30) at ./boost/python/handle.hpp:222
#3 boost::python::converter::shared_ptr_deleter::operator()
(this=0x6c1f30) at libs/python/src/converter/builtin_converters.cpp:35
#4 0x00007ffff7ff563a in _M_release (this=0x6c1f20) at
.../bits/shared_ptr_base.h:154
#5 ~__shared_count (this=<optimized out>, __in_chrg=<optimized out>)
at .../bits/shared_ptr_base.h:684
#6 ~__shared_ptr (this=<optimized out>, __in_chrg=<optimized out>)
at .../bits/shared_ptr_base.h:1123
#7 ~shared_ptr (this=<optimized out>, __in_chrg=<optimized out>) at
.../bits/shared_ptr.h:93
#8 _Destroy<std::shared_ptr<X> > (__pointer=<optimized out>) at
.../bits/stl_construct.h:98
#9 __destroy<std::shared_ptr<X>*> (__last=<optimized out>, __first=0x678920)
at .../bits/stl_construct.h:108
#10 _Destroy<std::shared_ptr<X>*> (__last=<optimized out>,
__first=<optimized out>)
at .../bits/stl_construct.h:137
#11 _Destroy<std::shared_ptr<X>*, std::shared_ptr<X> >
(__last=0x678930, __first=<optimized out>)
at .../bits/stl_construct.h:206
#12 std::vector<std::shared_ptr<X>, std::allocator<std::shared_ptr<X>
> >::~vector (this=0x7ffff7ff7a60 <init_module_pymodule()::v>,
__in_chrg=<optimized out>) at .../bits/stl_vector.h:434
#13 0x00007ffff6d24e69 in __run_exit_handlers () from /lib64/libc.so.6
#14 0x00007ffff6d24eb5 in exit () from /lib64/libc.so.6
#15 0x00007ffff6d0db1c in __libc_start_main () from /lib64/libc.so.6
#16 0x00000000004007a1 in _start ()
Is this a new behaviour change, or a bug, or was it always dangerous
and I have just been lucky until now?
Many thanks,
Charlie
_______________________________________________
Cplusplus-sig mailing list
Cplu...@python.org
https://mail.python.org/mailman/listinfo/cplusplus-sig