GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-94215: Fix reference count issue in exception_unwind by tiran · Pull Request #94659 · python/cpython

Conversation

@tiran

@tiran tiran commented Jul 7, 2022 •
edited by bedevere-bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member

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 [email protected]

  • Issue: GC crash _PyObject_AssertFailed with pdb #94215

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@tiran tiran added interpreter-core (Objects, Python, Grammar, and Parser dirs) type-crash A hard crash of the interpreter, possibly with a core dump needs backport to 3.11 only security fixes labels Jul 7, 2022
@tiran
tiran requested review from iritkatriel, markshannon and pablogsal July 7, 2022 15:09
@bedevere-bot bedevere-bot added the awaiting core review label Jul 7, 2022
iritkatriel
iritkatriel reviewed Jul 7, 2022
View reviewed changes
Comment thread Misc/NEWS.d/next/Core and Builtins/2022-07-07-17-07-00.gh-issue-94215.cXltGH.rst Resolved

Uh oh!

There was an error while loading. Please reload this page.

@tiran tiran added the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Jul 7, 2022
@bedevere-bot

bedevere-bot commented Jul 7, 2022

Copy link
Copy Markdown

🤖 New build scheduled with the buildbot fleet by @tiran for commit 990279b062ac4d61361ef7587e1977879606de52 🤖

If you want to schedule another build, you need to add the ":hammer: test-with-buildbots" label again.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-bot bedevere-bot removed the 🔨 test-with-buildbots Test PR w/ buildbots; report in status section label Jul 7, 2022
@tiran

tiran commented Jul 7, 2022 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member Author

The fix seems to introduce a reference leak:

test_sys_settrace leaked [17, 17, 17] references, sum=51
test_sys_setprofile leaked [4, 4, 4] references, sum=12

Leaking tests:

  • test.test_sys_settrace.JumpTestCase.test_no_jump_between_except_blocks
  • test.test_sys_settrace.JumpTestCase.test_no_jump_between_except_blocks_2
  • test.test_sys_settrace.JumpTestCase.test_no_jump_into_bare_except_block_from_try_block
  • test.test_sys_settrace.JumpTestCase.test_no_jump_into_qualified_except_block_from_try_block
  • test.test_sys_settrace.JumpTestCase.test_no_jump_out_of_bare_except_block
  • test.test_sys_settrace.JumpTestCase.test_no_jump_out_of_qualified_except_block
  • test.test_sys_settrace.JumpTestCase.test_no_jump_to_except_1
  • test.test_sys_settrace.JumpTestCase.test_no_jump_to_except_2
  • test.test_sys_settrace.JumpTestCase.test_no_jump_to_except_3
  • test.test_sys_settrace.JumpTestCase.test_no_jump_to_except_4
  • test.test_sys_settrace.JumpTestCase.test_no_jump_within_except_block
  • test.test_sys_setprofile.ProfileHookTestCase.test_raise_reraise
  • test.test_sys_setprofile.ProfileHookTestCase.test_raise_twice
./python -m test test_sys_setprofile --list-cases | while read line; do ./python -m test test_sys_setprofile -R:: -m $line || echo $line >> leaks.txt; done
All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@tiran

tiran commented Jul 7, 2022

Copy link
Copy Markdown
Member Author

@encukou How did you figure out the leaking tests so quickly? I had to figure out that shell one-liner to run each test function separately.

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@encukou

encukou commented Jul 7, 2022

Copy link
Copy Markdown
Member

Umm, manually: deleting chunks of the test suite & only keeping the deletion if the leaks stayed at [17, 17, 17] ;)

tiran reacted with laugh emoji
All reactions
  • 😄 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@tiran

tiran commented Jul 7, 2022 •
edited
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Member Author

My approach takes longer, but is less manual work.

encukou reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@brandtbucher

brandtbucher commented Jul 7, 2022

Copy link
Copy Markdown
Member

My approach takes longer, but is less manual work.

There's also ./python -m test.bisect_cmd -R:, which I use pretty frequently for these sorts of things. It will get it down to as few tests as possible (even just one, if it can).

tiran reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

ericsnowcurrently
ericsnowcurrently approved these changes Jul 7, 2022
View reviewed changes

@ericsnowcurrently ericsnowcurrently left a comment

Copy link
Copy Markdown
Member

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.

LGTM

At the least this seems to be an effective short-term solution. It may be valid for the long-term too. I've left some thoughts on the issue.

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
Comment thread Python/ceval.c Resolved

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-bot bedevere-bot added awaiting merge and removed awaiting core review labels Jul 7, 2022
@tiran tiran added the DO-NOT-MERGE label Jul 7, 2022
@brandtbucher

brandtbucher commented Jul 7, 2022

Copy link
Copy Markdown
Member

@tiran, applying this diff to your branch fixes the leaks for me:

diff --git a/Python/ceval.c b/Python/ceval.c
index 083f881807..e23bfda725 100644
--- a/Python/ceval.c
+++ b/Python/ceval.c
@@ -5683,6 +5683,8 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
                     err = maybe_call_line_trace(tstate->c_tracefunc,
                                                 tstate->c_traceobj,
                                                 tstate, frame, instr_prev);
+                    stack_pointer = _PyFrame_GetStackPointer(frame);
+                    frame->stacktop = -1;
                     if (err) {
                         /* trace function raised an exception */
                         next_instr++;
@@ -5690,9 +5692,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
                     }
                     /* Reload possibly changed frame fields */
                     next_instr = frame->prev_instr;
-
-                    stack_pointer = _PyFrame_GetStackPointer(frame);
-                    frame->stacktop = -1;
                 }
             }
         }
@@ -5795,11 +5794,6 @@ _PyEval_EvalFrameDefault(PyThreadState *tstate, _PyInterpreterFrame *frame, int
 
                 /* Pop remaining stack entries. */
                 PyObject **stackbase = _PyFrame_Stackbase(frame);
-                if (frame->stacktop != -1) {
-                    // frame_setlineno() may have popped off additional stacks in
-                    // frame_stack_pop(). Re-calculate stack pointer.
-                    stack_pointer = _PyFrame_GetStackPointer(frame);
-                }
                 while (stack_pointer > stackbase) {
                     PyObject *o = POP();
                     Py_XDECREF(o);

I'm not entirely sure why yet, but my understanding (gained over the last couple of hours) is that frame->stacktop is expected to always be -1 in this function, except when we're calling a trace function (since GC of frame objects needs to work correctly there). This looks like one place where we forget to set it back to -1 and reload the (possibly changed) stack pointer if an error is raised in while tracing...

...maybe?

ericsnowcurrently and iritkatriel reacted with thumbs up emoji
All reactions
  • 👍 2 reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

tiran and others added 2 commits July 7, 2022 22:31
@tiran @iritkatriel
pythongh-94215: Fix reference count issue in exception_unwind
968d0ba
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 <[email protected]>
@tiran
Let's try Brandt's patch
cee2887
@tiran
tiran force-pushed the gh-94215-jump-crash branch from 990279b to cee2887 Compare July 7, 2022 20:31
@brandtbucher brandtbucher mentioned this pull request Jul 8, 2022
gh-94215: Fix error handling for line-tracing events #94681
Merged
@tiran

tiran commented Jul 8, 2022

Copy link
Copy Markdown
Member Author

superseded by #94681

All reactions

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

@tiran tiran closed this Jul 8, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@iritkatriel iritkatriel iritkatriel left review comments
@ericsnowcurrently ericsnowcurrently ericsnowcurrently approved these changes
@markshannon markshannon Awaiting requested review from markshannon markshannon is a code owner
@pablogsal pablogsal Awaiting requested review from pablogsal
@gaogaotiantian gaogaotiantian Awaiting requested review from gaogaotiantian gaogaotiantian will be requested when the pull request is marked ready for review gaogaotiantian is a code owner

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

awaiting merge DO-NOT-MERGE interpreter-core (Objects, Python, Grammar, and Parser dirs) needs backport to 3.11 only security fixes type-crash A hard crash of the interpreter, possibly with a core dump

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

6 participants

@tiran @bedevere-bot @encukou @brandtbucher @iritkatriel @ericsnowcurrently
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.