From ffe37c9e674a375e99dbf71ebc059c276731b59d Mon Sep 17 00:00:00 2001 From: Shamil Date: Sun, 19 Oct 2025 22:24:28 +0300 Subject: [PATCH] gh-140306: Fix memory leaks in cross-interpreter data handling (GH-140307) (cherry picked from commit f9323213c98c9f1f7f3bf5af883b73047432fe50) Co-authored-by: Shamil --- ...2025-10-18-21-29-45.gh-issue-140306.xS5CcS.rst | 2 ++ Modules/_interpchannelsmodule.c | 2 +- Modules/_interpqueuesmodule.c | 2 +- Python/crossinterp.c | 15 ++++++++++++--- 4 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 Misc/NEWS.d/next/Core_and_Builtins/2025-10-18-21-29-45.gh-issue-140306.xS5CcS.rst diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-10-18-21-29-45.gh-issue-140306.xS5CcS.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-10-18-21-29-45.gh-issue-140306.xS5CcS.rst new file mode 100644 index 00000000000000..2178c4960636cb --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2025-10-18-21-29-45.gh-issue-140306.xS5CcS.rst @@ -0,0 +1,2 @@ +Fix memory leaks in cross-interpreter channel operations and shared +namespace handling. diff --git a/Modules/_interpchannelsmodule.c b/Modules/_interpchannelsmodule.c index 274bfacfed874b..ef9cf01ecbec5e 100644 --- a/Modules/_interpchannelsmodule.c +++ b/Modules/_interpchannelsmodule.c @@ -580,7 +580,7 @@ _channelitem_clear_data(_channelitem *item, int removed) { if (item->data != NULL) { // It was allocated in channel_send(). - (void)_release_xid_data(item->data, XID_IGNORE_EXC & XID_FREE); + (void)_release_xid_data(item->data, XID_IGNORE_EXC | XID_FREE); item->data = NULL; } diff --git a/Modules/_interpqueuesmodule.c b/Modules/_interpqueuesmodule.c index 03ed081efbae0d..872495d32fbf8f 100644 --- a/Modules/_interpqueuesmodule.c +++ b/Modules/_interpqueuesmodule.c @@ -431,7 +431,7 @@ _queueitem_clear_data(_queueitem *item) return; } // It was allocated in queue_put(). - (void)_release_xid_data(item->data, XID_IGNORE_EXC & XID_FREE); + (void)_release_xid_data(item->data, XID_IGNORE_EXC | XID_FREE); item->data = NULL; } diff --git a/Python/crossinterp.c b/Python/crossinterp.c index 16a23f0351cd26..542253c14de9b8 100644 --- a/Python/crossinterp.c +++ b/Python/crossinterp.c @@ -1153,8 +1153,8 @@ _release_xid_data(_PyXIData_t *xidata, int rawfree) { PyObject *exc = PyErr_GetRaisedException(); int res = rawfree - ? _PyXIData_Release(xidata) - : _PyXIData_ReleaseAndRawFree(xidata); + ? _PyXIData_ReleaseAndRawFree(xidata) + : _PyXIData_Release(xidata); if (res < 0) { /* The owning interpreter is already destroyed. */ _PyXIData_Clear(NULL, xidata); @@ -1805,6 +1805,15 @@ _PyXI_InitFailureUTF8(_PyXI_failure *failure, int _PyXI_InitFailure(_PyXI_failure *failure, _PyXI_errcode code, PyObject *obj) { + *failure = (_PyXI_failure){ + .code = code, + .msg = NULL, + .msg_owned = 0, + }; + if (obj == NULL) { + return 0; + } + PyObject *msgobj = PyObject_Str(obj); if (msgobj == NULL) { return -1; @@ -1813,7 +1822,7 @@ _PyXI_InitFailure(_PyXI_failure *failure, _PyXI_errcode code, PyObject *obj) // That happens automatically in _capture_current_exception(). const char *msg = _copy_string_obj_raw(msgobj, NULL); Py_DECREF(msgobj); - if (PyErr_Occurred()) { + if (msg == NULL) { return -1; } *failure = (_PyXI_failure){