Skip to content

Commit 08bea29

Browse files
[3.14] gh-112729: Correctly fail when the process is out of memory during interpreter creation (GH-139164) (GH-139168)
gh-112729: Correctly fail when the process is out of memory during interpreter creation (GH-139164) (cherry picked from commit d06113c) Co-authored-by: Peter Bierma <[email protected]>
1 parent a69bdab commit 08bea29

File tree

3 files changed

+18
-8
lines changed

3 files changed

+18
-8
lines changed

Lib/test/test_interpreters/test_stress.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
# Raise SkipTest if subinterpreters not supported.
88
import_helper.import_module('_interpreters')
99
from concurrent import interpreters
10+
from concurrent.interpreters import InterpreterError
1011
from .utils import TestBase
1112

1213

@@ -74,6 +75,14 @@ def run():
7475
start.set()
7576
support.gc_collect()
7677

78+
def test_create_interpreter_no_memory(self):
79+
import _interpreters
80+
_testcapi = import_helper.import_module("_testcapi")
81+
82+
with self.assertRaises(InterpreterError):
83+
_testcapi.set_nomemory(0, 1)
84+
_interpreters.create()
85+
7786

7887
if __name__ == '__main__':
7988
# Test needs to be a package, so we can do relative imports.
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix crash when calling :func:`concurrent.interpreters.create` when the
2+
process is out of memory.

Python/pylifecycle.c

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2298,18 +2298,17 @@ new_interpreter(PyThreadState **tstate_p,
22982298
interpreters: disable PyGILState_Check(). */
22992299
runtime->gilstate.check_enabled = 0;
23002300

2301-
PyInterpreterState *interp = PyInterpreterState_New();
2301+
// XXX Might new_interpreter() have been called without the GIL held?
2302+
PyThreadState *save_tstate = _PyThreadState_GET();
2303+
PyThreadState *tstate = NULL;
2304+
PyInterpreterState *interp;
2305+
status = _PyInterpreterState_New(save_tstate, &interp);
23022306
if (interp == NULL) {
2303-
*tstate_p = NULL;
2304-
return _PyStatus_OK();
2307+
goto error;
23052308
}
23062309
_PyInterpreterState_SetWhence(interp, whence);
23072310
interp->_ready = 1;
23082311

2309-
// XXX Might new_interpreter() have been called without the GIL held?
2310-
PyThreadState *save_tstate = _PyThreadState_GET();
2311-
PyThreadState *tstate = NULL;
2312-
23132312
/* From this point until the init_interp_create_gil() call,
23142313
we must not do anything that requires that the GIL be held
23152314
(or otherwise exist). That applies whether or not the new
@@ -2385,7 +2384,7 @@ new_interpreter(PyThreadState **tstate_p,
23852384
*tstate_p = NULL;
23862385
if (tstate != NULL) {
23872386
Py_EndInterpreter(tstate);
2388-
} else {
2387+
} else if (interp != NULL) {
23892388
PyInterpreterState_Delete(interp);
23902389
}
23912390
if (save_tstate != NULL) {

0 commit comments

Comments
 (0)