From: Peter Bierma Date: Fri, 19 Sep 2025 15:09:44 +0000 (-0400) Subject: [3.13] gh-112729: Correctly fail when the process is out of memory during interpreter... X-Git-Tag: v3.13.8~46 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=63dd27da3ba17a9584907cf179c0f33ba92de98a;p=thirdparty%2FPython%2Fcpython.git [3.13] gh-112729: Correctly fail when the process is out of memory during interpreter creation (GH-139164) (GH-139169) * gh-112729: Correctly fail when the process is out of memory during interpreter creation (GH-139164) (cherry picked from commit d06113c7a7cac76a28847702685e601b79f71bf8) --- diff --git a/Lib/test/test_interpreters/test_stress.py b/Lib/test/test_interpreters/test_stress.py index fae2f38cb553..a39c9352f728 100644 --- a/Lib/test/test_interpreters/test_stress.py +++ b/Lib/test/test_interpreters/test_stress.py @@ -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 index 000000000000..07485fcf9f1a --- /dev/null +++ b/Misc/NEWS.d/next/Library/2025-09-19-09-36-42.gh-issue-112729.mmty0_.rst @@ -0,0 +1,2 @@ +Fix crash when calling ``_interpreters.create`` when the +process is out of memory. diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 01fd36e52fc1..8cc6bd0fa789 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -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) {