diff options
author | Eddie Elizondo <eelizondo@fb.com> | 2020-02-04 10:29:25 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-02-04 10:29:25 (GMT) |
commit | 4590f72259ecbcea66e12a28af14d867255d2e66 (patch) | |
tree | afb692345720572c2dfe8c632d0e45dbf7eee1da /Misc | |
parent | b6999e5690c7006b0ba4049cfd638513c982a90c (diff) | |
download | cpython-4590f72259ecbcea66e12a28af14d867255d2e66.zip cpython-4590f72259ecbcea66e12a28af14d867255d2e66.tar.gz cpython-4590f72259ecbcea66e12a28af14d867255d2e66.tar.bz2 |
bpo-38076 Clear the interpreter state only after clearing module globals (GH-18039)
Currently, during runtime destruction, `_PyImport_Cleanup` is clearing the interpreter state before clearing out the modules themselves. This leads to a segfault on modules that rely on the module state to clear themselves up.
For example, let's take the small snippet added in the issue by @DinoV :
```
import _struct
class C:
def __init__(self):
self.pack = _struct.pack
def __del__(self):
self.pack('I', -42)
_struct.x = C()
```
The module `_struct` uses the module state to run `pack`. Therefore, the module state has to be alive until after the module has been cleared out to successfully run `C.__del__`. This happens at line 606, when `_PyImport_Cleanup` calls `_PyModule_Clear`. In fact, the loop that calls `_PyModule_Clear` has in its comments:
> Now, if there are any modules left alive, clear their globals to minimize potential leaks. All C extension modules actually end up here, since they are kept alive in the interpreter state.
That means that we can't clear the module state (which is used by C Extensions) before we run that loop.
Moving `_PyInterpreterState_ClearModules` until after it, fixes the segfault in the code snippet.
Finally, this updates a test in `io` to correctly assert the error that it now throws (since it now finds the io module state). The test that uses this is: `test_create_at_shutdown_without_encoding`. Given this test is now working is a proof that the module state now stays alive even when `__del__` is called at module destruction time. Thus, I didn't add a new tests for this.
https://bugs.python.org/issue38076
Diffstat (limited to 'Misc')
-rw-r--r-- | Misc/NEWS.d/next/C API/2020-01-17-11-37-05.bpo-38076.cxfw2x.rst | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/Misc/NEWS.d/next/C API/2020-01-17-11-37-05.bpo-38076.cxfw2x.rst b/Misc/NEWS.d/next/C API/2020-01-17-11-37-05.bpo-38076.cxfw2x.rst new file mode 100644 index 0000000..d9f6dc3 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-01-17-11-37-05.bpo-38076.cxfw2x.rst @@ -0,0 +1,2 @@ +Fix to clear the interpreter state only after clearing module globals to +guarantee module state access from C Extensions during runtime destruction |