Analyze and document libevwrapper atexit cleanup bug causing Python shutdown crashes #680
+567
−0
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.
Description
The
atexitcallback inlibevreactor.pywas registered with_global_loop=Noneat import time, causing it to receiveNoneduring shutdown instead of the actual loop instance. This prevented cleanup from running, leaving active libev callbacks that could execute during Python shutdown and crash.This PR provides comprehensive analysis and test cases demonstrating the bug before implementing a fix.
Changes
LIBEV_SHUTDOWN_ANALYSIS.md: Comprehensive analysis document identifying the root cause and 6 different crash scenarios:
tests/unit/io/test_libevreactor_shutdown.py: Test suite demonstrating the bug:
test_atexit_callback_registered_with_none()- Shows atexit capturesNoneinstead of actual looptest_shutdown_crash_scenario_subprocess()- Subprocess test showing exact bug scenariotest_callback_during_shutdown_scenario()- Documents crash conditionsRoot Cause
Line 231 in
libevreactor.py:The
partialfunction capturesNoneat import time. Later when_global_loopis set to aLibevLoopinstance, the atexit callback still hasNonecaptured, so cleanup never runs.Proposed Fix (for approval)
Replace the problematic line with a wrapper function that looks up the current
_global_loopvalue at shutdown time:This is a minimal 6-line change that ensures cleanup runs on the actual loop instance without requiring C extension modifications.
Pre-review checklist
./docs/source/.Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.