-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
shared_ptrs to Python-derived instances outlive the associated Python object #1546
Comments
This looks like a better description and solution than the existing #1145 (which is the same issue). |
See my comment on the associated PR when using the workaround proposed here in a multithreaded environment. |
Thanks @iwanders - have updated the PR. |
Thanks for incorporating the addition so quickly @cdyson37 , it may be a good idea to also edit your workaround at the top of this issue such that people who copy paste that have the fix as well. |
I've tweaked the workaround + patch above, but it would be good to get this merged, or at least looked at. Maybe I can call in a favour from @wjakob? :) We had a chat about the custodian_and_ward thing a while ago by email. |
Using workaround from here: pybind/pybind11#1546
There is a bug when c++ object is implicitly converted from src as src is separate from C++ instance then. Following fixes it:
|
Addresses C++/Python shared object crash fix pybind#1546 (comment)
Addresses C++/Python shared object crash fix pybind#1546 (comment)
Just to consolidate, I'm closing this in lieu of #1333. Feel free to reopen if you think this addresses a new / niche case. |
Issue description
Storing shared_ptrs to Python-derived instances for later execution causes virtual functions to fail if the Python instance has subsequently been destroyed.
Tested on master: e7761e3 / Python 3.6 / gcc 7.2
Reproducible example code
C++
Python
Output
Output (with 'del' removed)
Workaround:
Add the following (tweaked by @iwanders - thanks)
This replaces the default shared_ptr caster with one that keeps the Python object alive, using the aliasing constructor of shared_ptr.
Comment
Ideally, whenever there's a shared_ptr to a Python-derived object, that shared_ptr should keep the Python side of the object alive. The above seems to do that, but there may be a more sensible approach!
I also tried a workaround using
python_wrap.def ("__init__", [] (py::detail::value_and_holder &v_h) {
and constructing a std::shared_ptr in a similar fashion, but I found that I couldn't capture "self" without passing it in as an additional argument (i.e.
testmodule.Base.__init__ (self, self)
).I've also tried patching cast.h (below) as a proof-of-concept, and that appears to work (thanks @iwanders for the tweak)
The text was updated successfully, but these errors were encountered: