]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.13] gh-112729: Correctly fail when the process is out of memory during interpreter...
authorPeter Bierma <zintensitydev@gmail.com>
Fri, 19 Sep 2025 15:09:44 +0000 (11:09 -0400)
committerGitHub <noreply@github.com>
Fri, 19 Sep 2025 15:09:44 +0000 (15:09 +0000)
* gh-112729: Correctly fail when the process is out of memory during interpreter creation (GH-139164)

(cherry picked from commit d06113c7a7cac76a28847702685e601b79f71bf8)

Lib/test/test_interpreters/test_stress.py
Misc/NEWS.d/next/Library/2025-09-19-09-36-42.gh-issue-112729.mmty0_.rst [new file with mode: 0644]
Python/pylifecycle.c

index fae2f38cb5534bc62509a94963d3f3a33b17e5d9..a39c9352f728d38265dab8c4a13b1fb5f801e078 100644 (file)
@@ -7,6 +7,7 @@ from test.support import threading_helper
 # Raise SkipTest if subinterpreters not supported.
 import_helper.import_module('_interpreters')
 from test.support import interpreters
+from test.support.interpreters import InterpreterError
 from .utils import TestBase
 
 
@@ -74,6 +75,14 @@ class StressTests(TestBase):
             start.set()
         support.gc_collect()
 
+    def test_create_interpreter_no_memory(self):
+        import _interpreters
+        _testcapi = import_helper.import_module("_testcapi")
+
+        with self.assertRaises(InterpreterError):
+            _testcapi.set_nomemory(0, 1)
+            _interpreters.create()
+
 
 if __name__ == '__main__':
     # Test needs to be a package, so we can do relative imports.
diff --git a/Misc/NEWS.d/next/Library/2025-09-19-09-36-42.gh-issue-112729.mmty0_.rst b/Misc/NEWS.d/next/Library/2025-09-19-09-36-42.gh-issue-112729.mmty0_.rst
new file mode 100644 (file)
index 0000000..07485fc
--- /dev/null
@@ -0,0 +1,2 @@
+Fix crash when calling ``_interpreters.create`` when the
+process is out of memory.
index 01fd36e52fc11ef50fc717e71282643a6eb055c0..8cc6bd0fa7890604f44d6b0a2a0a3c40c1406433 100644 (file)
@@ -2301,18 +2301,17 @@ new_interpreter(PyThreadState **tstate_p,
        interpreters: disable PyGILState_Check(). */
     runtime->gilstate.check_enabled = 0;
 
-    PyInterpreterState *interp = PyInterpreterState_New();
+    // XXX Might new_interpreter() have been called without the GIL held?
+    PyThreadState *save_tstate = _PyThreadState_GET();
+    PyThreadState *tstate = NULL;
+    PyInterpreterState *interp;
+    status = _PyInterpreterState_New(save_tstate, &interp);
     if (interp == NULL) {
-        *tstate_p = NULL;
-        return _PyStatus_OK();
+        goto error;
     }
     _PyInterpreterState_SetWhence(interp, whence);
     interp->_ready = 1;
 
-    // XXX Might new_interpreter() have been called without the GIL held?
-    PyThreadState *save_tstate = _PyThreadState_GET();
-    PyThreadState *tstate = NULL;
-
     /* From this point until the init_interp_create_gil() call,
        we must not do anything that requires that the GIL be held
        (or otherwise exist).  That applies whether or not the new
@@ -2388,7 +2387,7 @@ error:
     *tstate_p = NULL;
     if (tstate != NULL) {
         Py_EndInterpreter(tstate);
-    } else {
+    } else if (interp != NULL) {
         PyInterpreterState_Delete(interp);
     }
     if (save_tstate != NULL) {