From: Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> Date: Tue, 30 Jun 2026 11:24:38 +0000 (+0200) Subject: [3.14] gh-152635: Raise MemoryError when the lock allocation fails in `_interpchannel... X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=589833e0a4fae6b476107f5fb345d8058ce2712a;p=thirdparty%2FPython%2Fcpython.git [3.14] gh-152635: Raise MemoryError when the lock allocation fails in `_interpchannels.create()` (GH-152642) (#152672) gh-152635: Raise MemoryError when the lock allocation fails in `_interpchannels.create()` (GH-152642) Previously, an allocation failure when creating the lock for a channel in `_interpchannels` would trigger an assert. Caused by `handle_channel_error` being passed an error code of -1 which is only allowed if an exception has been set. (in this case, no exception was set) `channelsmod_create` now forwards the error code from `channel_create` which `handle_channel_error` already handled. (cherry picked from commit b383aa6e1a8ea53fdeed88c71fbc34d8b2d1fde9) Co-authored-by: Steve Stagg Co-authored-by: sobolevn --- diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-06-29-23-29-14.gh-issue-152635.O21J0O.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-29-23-29-14.gh-issue-152635.O21J0O.rst new file mode 100644 index 000000000000..dadb25fc7c44 --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-29-23-29-14.gh-issue-152635.O21J0O.rst @@ -0,0 +1,2 @@ +Fix a crash caused when running out of memory creating a +:mod:`!_interpchannels` channel. Now a :exc:`MemoryError` is correctly raised. diff --git a/Modules/_interpchannelsmodule.c b/Modules/_interpchannelsmodule.c index 09e0d310b00c..afaa42562771 100644 --- a/Modules/_interpchannelsmodule.c +++ b/Modules/_interpchannelsmodule.c @@ -354,7 +354,7 @@ clear_module_state(module_state *state) #define ERR_CHANNEL_INTERP_CLOSED -4 #define ERR_CHANNEL_EMPTY -5 #define ERR_CHANNEL_NOT_EMPTY -6 -#define ERR_CHANNEL_MUTEX_INIT -7 +#define ERR_CHANNEL_MUTEX_INIT -7 // currently unused #define ERR_CHANNELS_MUTEX_INIT -8 #define ERR_NO_NEXT_CHANNEL_ID -9 #define ERR_CHANNEL_CLOSED_WAITING -10 @@ -427,10 +427,6 @@ handle_channel_error(int err, PyObject *mod, int64_t cid) "if not empty (try force=True)", cid); } - else if (err == ERR_CHANNEL_MUTEX_INIT) { - PyErr_SetString(state->ChannelError, - "can't initialize mutex for new channel"); - } else if (err == ERR_CHANNELS_MUTEX_INIT) { PyErr_SetString(state->ChannelError, "can't initialize mutex for channel management"); @@ -1744,7 +1740,8 @@ channel_create(_channels *channels, struct _channeldefaults defaults) { PyThread_type_lock mutex = PyThread_allocate_lock(); if (mutex == NULL) { - return ERR_CHANNEL_MUTEX_INIT; + PyErr_NoMemory(); + return -1; } _channel_state *chan = _channel_new(mutex, defaults); if (chan == NULL) { @@ -2938,7 +2935,7 @@ channelsmod_create(PyObject *self, PyObject *args, PyObject *kwds) int64_t cid = channel_create(&_globals.channels, defaults); if (cid < 0) { - (void)handle_channel_error(-1, self, cid); + (void)handle_channel_error(cid, self, cid); return NULL; } module_state *state = get_module_state(self);