You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Fix crashes during interpreter shutdown on all Python versions (3.2.6)
Backport of PR #499 (master) to maint/3.2 for greenlet 3.2.6, with all
shutdown guards made unconditional across Python 3.9-3.13.
The previous backport (3.2.5 / PR #495) only guarded Python < 3.11,
but the vulnerability exists on ALL Python versions: Py_IsFinalizing()
is set AFTER atexit handlers complete inside Py_FinalizeEx.
Two independent guards now protect all shutdown phases:
1. g_greenlet_shutting_down — atexit handler registered at module init
(LIFO = runs first). Covers the atexit phase where
Py_IsFinalizing() is still False.
2. Py_IsFinalizing() — covers the GC collection and later phases.
A compatibility shim maps to _Py_IsFinalizing() on Python < 3.13.
These guards are checked in mod_getcurrent, PyGreenlet_GetCurrent,
GreenletChecker, MainGreenletExactChecker, ContextExactChecker,
clear_deleteme_list, ThreadState destructor,
_green_dealloc_kill_started_non_main_greenlet, and AddPendingCall.
Additional hardening:
- clear_deleteme_list() uses std::swap (zero-allocation)
- deleteme vector uses std::allocator (system malloc)
- ThreadState uses std::malloc/std::free
- clear_deleteme_list() preserves pending Python exceptions
TDD-certified: tests fail on greenlet 3.3.2 and pass with the fix
across Python 3.10-3.14. Docker verification on Python 3.9 and 3.10
confirms GUARDED on the maint/3.2 branch.
Also fixes:
- SPDX license identifier: Python-2.0 -> PSF-2.0
- test_dealloc_catches_GreenletExit_throws_other: use
sys.unraisablehook for pytest compatibility
- test_version: skip gracefully on old setuptools
- Flaky USS memory test on Windows
Made-with: Cursor
0 commit comments