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 — Crash when inspecting frame of generator · Issue #94262 · python/cpython

Crash when inspecting frame of generator #94262

New issue
Copy link
New issue
Copy link
Closed
Closed
Crash when inspecting frame of generator#94262
Copy link
Assignees
markshannon
Labels
3.11only security fixesonly security fixesrelease-blockertype-crashA hard crash of the interpreter, possibly with a core dumpA hard crash of the interpreter, possibly with a core dump

Description

@kumaraditya303
kumaraditya303
opened on Jun 25, 2022
Issue body actions

Crash report

This was discovered in an asyncio program when interrupted with CTRL - C.
Minimal Reproducer:

import gc
import inspect

gc.set_threshold(1, 0, 0)
f = []

def cb(*args):
    f.append(inspect.stack())

gc.callbacks.append(cb)

def gen():
    yield 1

g = gen()
g.__next__()

Error messages

python: Python/ceval.c:5436: _PyEval_EvalFrameDefault: Assertion `frame->frame_obj == NULL' failed.
Aborted (core dumped)

Your environment

  • CPython versions tested on: Python 3.12.0a0 51fd4de, Python 3.11.0b3+ 41e4b42
  • Operating system and architecture: Linux 5.4.0-1074-azure

cc @markshannon @pablogsal

Activity

  1. kumaraditya303
    added
    3.11only security fixesonly security fixes
    type-crashA hard crash of the interpreter, possibly with a core dumpA hard crash of the interpreter, possibly with a core dump
    3.12only security fixesonly security fixes
    release-blocker
    on Jun 25, 2022
  2. kumaraditya303
    assigned
    markshannon
    on Jun 26, 2022
  3. markshannon commented on Jun 27, 2022

    @markshannon
    markshannon
    on Jun 27, 2022
    Member
    More actions

    This is tricky.

    The fundamental problem, IMO, is that almost any memory allocation can run arbitrary code. This makes it really difficult to reason about the state of the VM.

    In the short term, we should handle the case where frame->frame_obj != NULL when creating a generator, but there are bound other issues, as the generator and frame object are may not be an introspectable state.

    In the longer term, I'd like to only run the GC, and/or finalizers, when the VM is a known state; as we do with interrupts.

    I'm concerned that this shows up from an interrupt. It shouldn't.

  4. kumaraditya303 commented on Jun 27, 2022

    @kumaraditya303
    kumaraditya303
    on Jun 27, 2022
    ContributorAuthor
    More actions

    The fundamental problem, IMO, is that almost any memory allocation can run arbitrary code. This makes it really difficult to reason about the state of the VM.

    I agree, not only the state of VM but also any other object state can be mutated which in some can lead to memory leak or worse crash.

    I'm concerned that this shows up from an interrupt. It shouldn't.

    It was really hard to reproduce the error, my current theory is that if an interrupt happens while executing __del__ of an object and the interpreter creates a traceback to print, it can create a frame object for a generator and it causes a hard crash while the exception is propagated to the generator.

  5. kumaraditya303 commented on Jun 27, 2022

    @kumaraditya303
    kumaraditya303
    on Jun 27, 2022
    ContributorAuthor
    More actions

    I was correct about my theory, the following code sample demonstrates how KeyboardInterrupt can lead to crash:

    import gc
    gc.set_threshold(1, 0, 0)
    
    class Sneaky:
        def __del__(self):
            raise KeyboardInterrupt
    
    
    def gen():
        yield 1
    
    sneaky = Sneaky()
    sneaky._s = Sneaky()
    sneaky._s._s = sneaky
    del sneaky
    
    g = gen()

    Crash:

    Exception ignored in: <function Sneaky.__del__ at 0x7fbfa49220a0>
    Traceback (most recent call last):
      File "/workspaces/cpython/main.py", line 6, in __del__
        raise KeyboardInterrupt
        ^^^^^^^^^^^^^^^^^^^^^^^
    KeyboardInterrupt: 
    Exception ignored in: <function Sneaky.__del__ at 0x7fbfa49220a0>
    Traceback (most recent call last):
      File "/workspaces/cpython/main.py", line 6, in __del__
        raise KeyboardInterrupt
        ^^^^^^^^^^^^^^^^^^^^^^^
    KeyboardInterrupt: 
    python: Python/ceval.c:5477: _PyEval_EvalFrameDefault: Assertion `frame->frame_obj == NULL' failed.
    Reacted by Michael Droettboom
  6. markshannon commented on Jun 27, 2022

    @markshannon
    markshannon
    on Jun 27, 2022
    Member
    More actions

    Thanks @kumaraditya303 that's really helpful.

  7. markshannon commented on Jun 28, 2022

    @markshannon
    markshannon
    on Jun 28, 2022
    Member
    More actions

    Turns out that the fix isn't that hard.

    The problem isn't really the GC behavior* but that partially constructed frames are visible to Python and C extensions.
    We fix this by not creating frame objects for partially constructed frames.

    *The behavior of the GC and finalization is a problem, but not the problem here.

  8. ezio-melotti
    added this to Release and Deferred blockers 🚫on Jun 30, 2022
  9. markshannon
    added a commit that references this issue on Jul 1, 2022

    GH-94262: Don't create frame objects for frames that aren't yet compl…

    544531d
  10. miss-islington
    added a commit that references this issue on Jul 1, 2022

    pythonGH-94262: Don't create frame objects for frames that aren't yet…

    96cbfad
  11. markshannon
    removed
    3.12only security fixesonly security fixes
    on Jul 1, 2022
  12. pablogsal
    closed this as completedon Jul 4, 2022
  13. pablogsal
    added a commit that references this issue on Jul 4, 2022

    [3.11] GH-94262: Don't create frame objects for frames that aren't ye…

    68f5fa6
  14. pablogsal
    moved this to Done in Release and Deferred blockers 🚫on Jul 4, 2022
  15. pablogsal commented on Jul 4, 2022

    @pablogsal
    pablogsal
    on Jul 4, 2022
    Member
    More actions

    Thanks, @markshannon and @kumaraditya303 for the work! 🎉

    Reacted by Kumar Aditya
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

  • @markshannon
    markshannon

Labels

3.11only security fixesonly security fixesrelease-blockertype-crashA hard crash of the interpreter, possibly with a core dumpA hard crash of the interpreter, possibly with a core dump

Projects

  • Release and Deferred blockers 🚫
    Status
    Done
    Show more project fields

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions

You are visitor 01402503 — 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.