-
-
Notifications
You must be signed in to change notification settings - Fork 34.5k
GH-93252: Fix error handling for failed Python calls #94693
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
Changes from 1 commit
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
- Loading branch information
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -6410,7 +6410,7 @@ _PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func, | |
| } | ||
| if (initialize_locals(tstate, func, localsarray, args, argcount, kwnames)) { | ||
| assert(frame->owner != FRAME_OWNED_BY_GENERATOR); | ||
| _PyFrame_Clear(frame); | ||
| _PyEvalFrameClearAndPop(tstate, frame); | ||
| return NULL; | ||
| } | ||
| return frame; | ||
|
|
@@ -6432,6 +6432,10 @@ _PyEvalFramePushAndInit(PyThreadState *tstate, PyFunctionObject *func, | |
| static void | ||
| _PyEvalFrameClearAndPop(PyThreadState *tstate, _PyInterpreterFrame * frame) | ||
| { | ||
| PyObject **base = (PyObject **)frame; | ||
| // Make sure that this is, indeed, the top frame. We can't check this in | ||
| // _PyThreadState_PopFrame, since f_code is already cleared at that point: | ||
| assert(base + frame->f_code->co_framesize == tstate->datastack_top); | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @pablogsal, just curious: does adding this assert (and not the fix) make tons of tests crash on your build? If so, my theory is that your compiler is optimizing out the old assert, since the failing case is always undefined behavior according to the C standard.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will test this night or tomorrow, but I checked and I was indeed compiling in debug mode with asserts, so the old assert should have triggered. I'm curious to see what's going on so I will also investigate that, but that won't affect this issue or the PR, is just that I'm very curious to see what's going on there :)
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well, even if asserts were turned on, the inequality comparison between the pointers would be undefined if they're part of different allocations. Which is exactly the situation it was checking for! So if the compiler could somehow prove that the comparison it was always true when the result was defined, it could have optimized it into
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But yeah, it doesn't affect this PR. The thing that's better about this new assert is that it's never undefined, and we don't need to overflow our stack chunk to trigger it. One failed call should do it (which is why so many tests crash if you add this without the fix).
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I don't think so because I was compiling with -O0. If the compiler was being smart there I want my money back 🤣 |
||
| tstate->recursion_remaining--; | ||
| assert(frame->frame_obj == NULL || frame->frame_obj->f_frame == frame); | ||
| assert(frame->owner == FRAME_OWNED_BY_THREAD); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.