Bug report
Bug description:
Bug report
Bug summary
There is a known memory leak in Python/crossinterp.c related to the teardown of sub-interpreters when they share data.
When a sub-interpreter packages data into _PyXIData_t and passes it to a receiving interpreter, the receiver is expected to call _PyXIData_Release to free it. However, if the originating interpreter is destroyed before the receiver calls release, the original interpreter's memory context is lost.
In _xidata_release (Python/crossinterp.c around line 1049), the code correctly identifies this state:
PyInterpreterState *interp = _PyInterpreterState_LookUpID(
_PyXIData_INTERPID(xidata));
if (interp == NULL) {
// The interpreter was already destroyed.
// This function shouldn't have been called.
// XXX Someone leaked some memory...
Because the originating interpreter is gone, Python intentionally leaks xidata->obj to avoid a use-after-free segfault.
Proposed Solution Architecture
To resolve this without crashing, we would need to track cross-interpreter data at the interpreter level:
- Modify
PyInterpreterState to include a thread-safe registry tracking all active _PyXIData_t instances created by that interpreter.
- Register instances during
_PyCode_GetXIData and deregister them during _xidata_release.
- Modify
Py_EndInterpreter teardown to check this registry. If outstanding shared data exists, the shutting-down interpreter must either block until it is released, or forcefully invalidate/free the shared data (using an is_invalidated flag) before tearing down its own obmalloc state.
I'm opening this issue to get feedback on the proposed architecture before starting a Pull Request.
CPython versions tested on:
main branch
CPython versions tested on:
CPython main branch
Operating systems tested on:
Windows
Linked PRs
Bug report
Bug description:
Bug report
Bug summary
There is a known memory leak in
Python/crossinterp.crelated to the teardown of sub-interpreters when they share data.When a sub-interpreter packages data into
_PyXIData_tand passes it to a receiving interpreter, the receiver is expected to call_PyXIData_Releaseto free it. However, if the originating interpreter is destroyed before the receiver calls release, the original interpreter's memory context is lost.In
_xidata_release(Python/crossinterp.caround line 1049), the code correctly identifies this state:Because the originating interpreter is gone, Python intentionally leaks
xidata->objto avoid a use-after-free segfault.Proposed Solution Architecture
To resolve this without crashing, we would need to track cross-interpreter data at the interpreter level:
PyInterpreterStateto include a thread-safe registry tracking all active_PyXIData_tinstances created by that interpreter._PyCode_GetXIDataand deregister them during_xidata_release.Py_EndInterpreterteardown to check this registry. If outstanding shared data exists, the shutting-down interpreter must either block until it is released, or forcefully invalidate/free the shared data (using anis_invalidatedflag) before tearing down its ownobmallocstate.I'm opening this issue to get feedback on the proposed architecture before starting a Pull Request.
CPython versions tested on:
mainbranchCPython versions tested on:
CPython main branch
Operating systems tested on:
Windows
Linked PRs