diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2026-06-18-17-31-02.gh-issue-151126.HubUYi.rst b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-18-17-31-02.gh-issue-151126.HubUYi.rst new file mode 100644 index 000000000000000..6714451b45fb1ff --- /dev/null +++ b/Misc/NEWS.d/next/Core_and_Builtins/2026-06-18-17-31-02.gh-issue-151126.HubUYi.rst @@ -0,0 +1,3 @@ +Fix crashes when interpreter queues run out of memory while being listed or +shared between interpreters. These cases now raise a proper +:exc:`MemoryError`. diff --git a/Modules/_interpqueuesmodule.c b/Modules/_interpqueuesmodule.c index 9979cd3457e1014..db2ecd19e9c3d0a 100644 --- a/Modules/_interpqueuesmodule.c +++ b/Modules/_interpqueuesmodule.c @@ -1042,9 +1042,10 @@ _queues_list_all(_queues *queues, int64_t *p_count) { struct queue_id_and_info *qids = NULL; PyThread_acquire_lock(queues->mutex, WAIT_LOCK); - struct queue_id_and_info *ids = PyMem_NEW(struct queue_id_and_info, + struct queue_id_and_info *ids = PyMem_New(struct queue_id_and_info, (Py_ssize_t)(queues->count)); if (ids == NULL) { + PyErr_NoMemory(); goto done; } _queueref *ref = queues->head; @@ -1321,13 +1322,26 @@ static void * _queueid_xid_new(int64_t qid) { _queues *queues = _get_global_queues(); - if (_queues_incref(queues, qid) < 0) { + int err = _queues_incref(queues, qid); + if (err < 0) { + assert(err == ERR_QUEUE_NOT_FOUND); + PyObject *mod = _get_current_module(); + if (mod == NULL) { + if (!PyErr_Occurred()) { + PyErr_SetString(PyExc_SystemError, + "missing " MODULE_NAME_STR " module"); + } + return NULL; + } + (void)handle_queue_error(err, mod, qid); + Py_DECREF(mod); return NULL; } struct _queueid_xid *data = PyMem_RawMalloc(sizeof(struct _queueid_xid)); if (data == NULL) { _queues_decref(queues, qid); + PyErr_NoMemory(); return NULL; } data->qid = qid;