Fix free-threading crash from untraversed deferred references in suspended greenlets#511
Open
kumaraditya303 wants to merge 13 commits into
Open
Fix free-threading crash from untraversed deferred references in suspended greenlets#511kumaraditya303 wants to merge 13 commits into
kumaraditya303 wants to merge 13 commits into
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
Hi — I'm a CPython core developer working on free-threading and maintainer of asyncio.
This PR fixes the crash on free-threading caused by deference reference counted objects not traversed by greenlet during GC traversal.
In free-threading, some of the refs to objects held by the interpreter uses a special reference type called "deferred reference". Such references are used on some objects like functions and classes to reduce reference contention on the objects and they must be traversed by the free-threaded GC so that it doesn't free these objects prematurely.
Greenlet currently crashes on free-threading because greenlets hold suspended frames which on free-threading can contain objects with deferred reference count. The suspended frames needs to be GC traversed so that the GC doesn't free objects early causing a crash at runtime exit.
In 3.15+, I exposed
_PyGC_VisitStackRefand_PyGC_VisitFrameStackin python/cpython#150767 which is used in this PR so that suspended frames of greenlets can be traversed by the GC. This fixes the crash and as a side effect also fixes the "A Cycle Of Greenlets Is A Leak" because suspended frames are now traversed so they can now be collected by the GC instead of being leaked. I have added tests on 3.15+ to ensure that suspended frames are gc collected and finalizers of locals are triggered properly.