-
-
Notifications
You must be signed in to change notification settings - Fork 30.6k
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
GC crash _PyObject_AssertFailed with pdb #94215
Comments
I can reproduce the issue in a pydebug build:
|
This might be related to #94438 |
It's seems to be a ref counting issue. The jump and frame_setlineno seems to reduce the reference count by one. Please notice that the case without jump starts interpreter shutdown with ref counts without jump
ref counts with jump
debug hack
|
The decref in
|
I'm not sure how much that function is covered by tests. Can you verify whether it is? |
|
The issue may be a bit more general. Notice the jump is going back to the bytecode so we need to ensure that jumps and continues are always idempotent |
Python 3.9 and 3.10 are affected, too. The reproducer crashes debug builds with assertion error
|
That's a different issue. See #91742 (comment) |
I have an isolated test case and instructions how to trace the reference count of the problematic object with gdb. def func():
def inner(v): pass
print(f"watch ((PyObject*){id(inner)})->ob_refcnt")
inner(
42
)
print("s n n n j 4 exit")
import pdb; pdb.set_trace()
func()
# tc.py
# build Python with --with-pydebug
# $ gdb ./python --ex "run tc.py"
# in pdb run: "s" "n" "n" "n" "CTRL+Z"
# in gdb run the "watch" command and continue ("c" "c")
# in pdb eventually run "n j 4" "exit" The reference counting problem could be a in |
…honGH-94563) (cherry picked from commit de58842) Co-authored-by: Christian Heimes <christian@python.org>
Bisection using that reproducer shows that the failure was introduced with "Zero cost" exception handling, back in gh-25729. |
I believe what's happening is that the ceval.c unwind code is unaware of the fact that frame_stack_pop already popped a couple of items from the stack. So stack_pointer is wrong there. It seems to fix it if I add
just before
|
The change introduces a reference leak
|
This code does neither crash nor cause a ref leak, though:
|
ah if you do this if I think you can just assign stack_pointer to _PyFrame_GetStackPointer(frame); |
Or just this and then we don't need to access
|
Maybe _PyFrame_GetStackPointer should return NULL when stack top is -1? |
I've been looking at Include/internal/pycore_frame.h, Objects/frameobject.c, and Python/ceval.c. Let me see if I've understood the problem.
Is all that correct? Related questions:
Based on all that, the possible solutions I see:
At the very least, solution (1) is an effective stopgap, if not a valid long-term solution. The answers to the above questions would help determine the validity of other possible solutions, as well as if solution (1) is sufficient long-term. (It would also be good to know what the performance impact of the various possible solutions are.) |
Should we be using |
Your summary matches my understanding of the problem. In fact I now understand the problem much better. Thank you!
|
I've opened gh-94666 for discussion of the broader concern about keeping |
Zero-cost exception handling did not take ``frame_setlineno()`` into account. It can pop off stacks. This can lead to a crash. Exception unwinding now re-calculates the stack pointer. Co-authored-by: Irit Katriel <1055913+iritkatriel@users.noreply.github.com>
* Re-enable crasher * Fix error handling for line-tracing events * blurb add
…thonGH-94681) * Re-enable crasher * Fix error handling for line-tracing events * blurb add (cherry picked from commit 23ee4a8) Co-authored-by: Brandt Bucher <brandtbucher@microsoft.com>
Main branch and 3.11 branch are fixed. Older branches are not affected. This issue is no longer a release blocker. 🎉 I'm leaving the ticket open for @markshannon to verify the patch after he is back. |
The changes look good to me. |
Reproducer:
Crash:
GDB stack trace (main)
Python versions tested:
cc @markshannon @pablogsal
The text was updated successfully, but these errors were encountered: