summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Include/internal/pycore_runtime_init.h1
-rw-r--r--Lib/test/test_exceptions.py14
-rw-r--r--Misc/NEWS.d/next/Core and Builtins/2023-10-15-22-18-45.gh-issue-109894.UAmo06.rst1
-rw-r--r--Objects/exceptions.c4
4 files changed, 16 insertions, 4 deletions
diff --git a/Include/internal/pycore_runtime_init.h b/Include/internal/pycore_runtime_init.h
index 574a3c1..4a48907 100644
--- a/Include/internal/pycore_runtime_init.h
+++ b/Include/internal/pycore_runtime_init.h
@@ -177,6 +177,7 @@ extern PyTypeObject _PyExc_MemoryError;
}, \
.last_resort_memory_error = { \
_PyObject_HEAD_INIT(&_PyExc_MemoryError) \
+ .args = (PyObject*)&_Py_SINGLETON(tuple_empty) \
}, \
}, \
}, \
diff --git a/Lib/test/test_exceptions.py b/Lib/test/test_exceptions.py
index 4031c5c..7f1d5ee 100644
--- a/Lib/test/test_exceptions.py
+++ b/Lib/test/test_exceptions.py
@@ -1791,6 +1791,20 @@ class ExceptionTests(unittest.TestCase):
gc_collect()
+ def test_memory_error_in_subinterp(self):
+ # gh-109894: subinterpreters shouldn't count on last resort memory error
+ # when MemoryError is raised through PyErr_NoMemory() call,
+ # and should preallocate memory errors as does the main interpreter.
+ # interp.static_objects.last_resort_memory_error.args
+ # should be initialized to empty tuple to avoid crash on attempt to print it.
+ code = f"""if 1:
+ import _testcapi
+ _testcapi.run_in_subinterp(\"[0]*{sys.maxsize}\")
+ exit(0)
+ """
+ rc, _, err = script_helper.assert_python_ok("-c", code)
+ self.assertIn(b'MemoryError', err)
+
class NameErrorTests(unittest.TestCase):
def test_name_error_has_name(self):
diff --git a/Misc/NEWS.d/next/Core and Builtins/2023-10-15-22-18-45.gh-issue-109894.UAmo06.rst b/Misc/NEWS.d/next/Core and Builtins/2023-10-15-22-18-45.gh-issue-109894.UAmo06.rst
new file mode 100644
index 0000000..2148536
--- /dev/null
+++ b/Misc/NEWS.d/next/Core and Builtins/2023-10-15-22-18-45.gh-issue-109894.UAmo06.rst
@@ -0,0 +1 @@
+Fixed crash due to improperly initialized static :exc:`MemoryError` in subinterpreter.
diff --git a/Objects/exceptions.c b/Objects/exceptions.c
index 4862345..e3e8e02 100644
--- a/Objects/exceptions.c
+++ b/Objects/exceptions.c
@@ -3700,10 +3700,6 @@ _PyExc_FiniTypes(PyInterpreterState *interp)
PyStatus
_PyExc_InitGlobalObjects(PyInterpreterState *interp)
{
- if (!_Py_IsMainInterpreter(interp)) {
- return _PyStatus_OK();
- }
-
if (preallocate_memerrors() < 0) {
return _PyStatus_NO_MEMORY();
}