-
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
fix: memory leak in cpp_function (#3228) #3229
Conversation
3c5696c
to
2bc438a
Compare
Very interesting and surprised Valgrind and our test suite isn't catching this. Do you think it's possible that this is related to this PyBind failing test case as well: #1301? Does that test case pass when added to this PR? Can the MRE be reduced to a test case to repro the error in a way our test suite can detect? |
Amazing indeed that this bug survived until now. This seems to be the commit that introduced the line you're changing: I don't know if it was a bug from the start, or if the bug is the result of subsequent changes. @yuantailing could you help by converting your #3228 reproducer to a unit test? Maybe an addition to test_callbacks.cpp,py. constructor_stats.h may be useful. But I'm very uncertain about the details, I haven't touched this code myself, and I don't know how the original unit test (see commit above) relates to constructor_stats.h. |
I think they are not related. The issue happens when a lvalue reference is passed to
Added. |
Yeah, I just realized it's a subtle issue with finalize_interperter and therefore is likely not an actual bug. |
I have added a test case to tests/test_embed/test_interpreter.cpp. Maybe the code can be moved to a more proper place. |
Constructor_Stats.h just defines a helper class with keeps track of all its' constructions / destructions. You may want to use that class instead of your counter class if it makes sense: pybind11/tests/constructor_stats.h Line 73 in e08a581
|
Thanks for your suggestions, fixed now. |
…at the new tests fails without the change in pybind11.h
The I also added two I will now look into moving the test elsewhere, because it's not specific to embedding, but specific to callbacks. |
…st_callbacks.cpp,py). This restores test_interpreter.cpp to the current state on master.
Done. @Skylion007, if my changes look good to you, please go ahead and merge (pending completion of CI jobs). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
(Assuming CI will be green.)
The purpose is to avoid the potential unused variable warning. Change it to
Looks good. |
Ah, got it. Thanks for the explanation! |
Description
The PR is related to #3228, and may be related to #1510 and pytorch/pytorch#5161.
Let's focus on
pybind11::cpp_function::initialize
. If the first argument is lvalue reference, the typeFunc
is deduced to lvalue reference (according to Template argument deduction). In this case,std::is_trivially_destructible<Func>
is always true, thereforerec->data
will never be deconstructed.To solve this issue, we should determine whether
rec->data
should be deconstructed according whether the type ofrec->data
(i.e.,capsule
) is trivially destructible.Suggested changelog entry:
A long-standing memory leak in ``py::cpp_function::initialize`` was fixed.