Skip to content

Commit d06113c

Browse files
gh-112729: Correctly fail when the process is out of memory during interpreter creation (GH-139164)
1 parent 2fd43a1 commit d06113c

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
@@ -2411,18 +2411,17 @@ new_interpreter(PyThreadState **tstate_p,
24112411
interpreters: disable PyGILState_Check(). */
24122412
runtime->gilstate.check_enabled = 0;
24132413

2414-
PyInterpreterState *interp = PyInterpreterState_New();
2414+
// XXX Might new_interpreter() have been called without the GIL held?
2415+
PyThreadState *save_tstate = _PyThreadState_GET();
2416+
PyThreadState *tstate = NULL;
2417+
PyInterpreterState *interp;
2418+
status = _PyInterpreterState_New(save_tstate, &interp);
24152419
if (interp == NULL) {
2416-
*tstate_p = NULL;
2417-
return _PyStatus_OK();
2420+
goto error;
24182421
}
24192422
_PyInterpreterState_SetWhence(interp, whence);
24202423
interp->_ready = 1;
24212424

2422-
// XXX Might new_interpreter() have been called without the GIL held?
2423-
PyThreadState *save_tstate = _PyThreadState_GET();
2424-
PyThreadState *tstate = NULL;
2425-
24262425
/* From this point until the init_interp_create_gil() call,
24272426
we must not do anything that requires that the GIL be held
24282427
(or otherwise exist). That applies whether or not the new
@@ -2498,7 +2497,7 @@ new_interpreter(PyThreadState **tstate_p,
24982497
*tstate_p = NULL;
24992498
if (tstate != NULL) {
25002499
Py_EndInterpreter(tstate);
2501-
} else {
2500+
} else if (interp != NULL) {
25022501
PyInterpreterState_Delete(interp);
25032502
}
25042503
if (save_tstate != NULL) {

0 commit comments

Comments
 (0)