-
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
[smart_holder] test_class_sh_mi_thunks (started from PR #4374) #4380
Conversation
See the I don't have a clue what could be wrong, thus far I used the core MI handling code only as a black box, more or less. A starting point for debugging would be to inspect the wrapped object created when |
|
It turns out only my print statements looked good, but the code is still failing/succeeding the same way as before. Needs more work. |
Not sure I understand, aren't those lines equivalent? |
Ok so they don't look completely equivalent, but they should become identical if you replace In both cases (dynamic vs static cast), the operation is safe and well defined. Do you agree @rwgk ? |
I backtracked, and now think I somehow missed a step before in my experiments (making two changes instead of one or similar): the behavior difference that I attributed to Concretely, with this diff m.def("make_derived_as_base0", []() -> std::shared_ptr<Base0> {
auto ret_der = std::make_shared<Derived>();
+ printf("\nLOOOK [%lu] %s:%d\n", (std::size_t) ret_der.get(), __FILE__, __LINE__); fflush(stdout);
auto ret = std::dynamic_pointer_cast<Base0>(ret_der);
+ printf("\nLOOOK [%lu] %s:%d\n", (std::size_t) ret.get(), __FILE__, __LINE__); fflush(stdout);
return ret;
});
@@ -66,7 +68,10 @@ TEST_SUBMODULE(mi_debug, m) {
// class_ OK
// classh FAIL
- m.def("get_vec_size_raw_ptr_derived", [](const Derived *obj) { return obj->vec.size(); });
+ m.def("get_vec_size_raw_ptr_derived", [](const Derived *obj) {
+ printf("\nLOOOK [%lu] %s:%d\n", (std::size_t) obj, __FILE__, __LINE__); fflush(stdout);
+ return obj->vec.size();
+ }); and
With
|
Please take a look at commit 248ac89. With that all 3 test_mi_debug.py tests pass, with That makes me think there is a problem in processing the But, with this additional diff
there is this output:
I.e. pybind11 figured out that the returned |
I don't think it is an issue that pybind11 is storing the The problem is that the conversion that happens later, "transforming" the Are you positive that in the smart holder branch all instances of unsafe casts (including |
I won't have any time this weekend, but next week I should be able to re-run the debugger in the smart holder branch and try to follow the code there. @rwgk |
Not sure anymore. I was thinking yes, but evidently not. The |
@bluescarni I think for the instance-from- - auto smhldr = pybindit::memory::smart_holder::from_shared_ptr(src);
+ auto smhldr = pybindit::memory::smart_holder::from_shared_ptr(std::shared_ptr<void>(src, const_cast<void *>(st.first))); In hindsight a blatant oversight. There could be a similar problem for the instance-from- I think I will want to test a full matrix of (from_raw_ptr, from_unique_ptr, from_shared_ptr) x (as_raw_ptr, as_unique_ptr, as_shared_ptr) and (from_base0, from_derived) x (as_base0, as_derived) combinations. I don't think I'll have the spare time to backport the fix(es) to pybind11 master. |
…USE_SH` defined or not defined. [ci skip]
```diff - auto smhldr = pybindit::memory::smart_holder::from_shared_ptr(src); + auto smhldr = pybindit::memory::smart_holder::from_shared_ptr(std::shared_ptr<void>(src, const_cast<void *>(st.first))); ```
@bluescarni The latest version of this PR passes testing with all clang sanitizers (Google toolchain). The fix for the I wouldn't be surprised if there are more oversights of the kind fixed in this PR. The use of C++ multiple inheritance is highly discouraged at Google, and the tool I need the smart_holder for (http://github.com/google/clif) does not support MI at all, therefore the interaction of MI with other features is not nearly as well exercised as other things. When I was done with my initial iteration of the smart_holder implementation, I tried to guess things that could go wrong in test_class_sh_disowning_mi.py, but your test case made it obviously that my attempts fell flat. If you have more tests, please let me know. I'll try to fix what I can. |
This PR also passed Google-internal global testing (internal testing ID OCL:494341648:BASE:494408109:1670696135236:b43772d2). I think it would be ideal to add more testing (and possibly fixes) for interactions with other features (disowning/re-owning, factory functions (init), trampolines, shared_from_this) but I will not be able to prioritize that anytime soon. I'll rename the new test, then mail it for review asap. Anyone looking here: please don't hesitate to comment. |
Thanks for the reviews! |
Description
This PR fixes failures for the tests originally added under PR #4374, for
shared_ptr
andunique_ptr
. The fix for theunique_ptr
case is not great, it conflicts with proper handling ofshared_from_this
(see PR #3023). That is probably a very rare edge case though, resulting in abad_weak_ptr
exception in the worst case.It would not be a surprise if there are more oversights of the kind fixed in this PR. The use of C++ multiple inheritance is highly discouraged at Google, and the tool the
smart_holder
was developed for (http://github.com/google/clif) does not support MI at all, therefore the interaction of MI with other features is not nearly as well exercised as other things.It would be ideal to add more testing (and possibly fixes) for interactions with other features (disowning/re-owning, factory functions (init), trampolines, shared_from_this), but we will not be able to prioritize that anytime soon. If you run into issues, please send PRs with reproducers, similar to PR #4374, we will try our best to fix.
Suggested changelog entry: