]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
[3.12] gh-109894: Fix initialization of static `MemoryError` in subinterpreter (gh...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Tue, 28 Nov 2023 02:41:53 +0000 (03:41 +0100)
committerGitHub <noreply@github.com>
Tue, 28 Nov 2023 02:41:53 +0000 (19:41 -0700)
Fixes GH-109894

* set `interp.static_objects.last_resort_memory_error.args` to empty tuple to avoid crash on `PyErr_Display()` call
* allow `_PyExc_InitGlobalObjects()` to be called on subinterpreter init

---------

(cherry picked from commit 47d3e2ed930a9f3d228aed4f62133737dae74cf7)

Co-authored-by: Radislav Chugunov <52372310+chgnrdv@users.noreply.github.com>
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
Include/internal/pycore_runtime_init.h
Lib/test/test_exceptions.py
Misc/NEWS.d/next/Core and Builtins/2023-10-15-22-18-45.gh-issue-109894.UAmo06.rst [new file with mode: 0644]
Objects/exceptions.c

index 660d7d7e237afb40ac594f73ba567e9da3600c31..e5f9e17efff24b606a38fd232a2937aebaeee1da 100644 (file)
@@ -119,6 +119,7 @@ extern PyTypeObject _PyExc_MemoryError;
                 }, \
                 .last_resort_memory_error = { \
                     _PyObject_HEAD_INIT(&_PyExc_MemoryError) \
+                    .args = (PyObject*)&_Py_SINGLETON(tuple_empty) \
                 }, \
             }, \
         }, \
index ad0b7c2154c020c8d022c3a201bb6512a1b520bf..2d6c3336744b7e7c5d6b22a4d60c96736bb2a197 100644 (file)
@@ -1785,6 +1785,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 (file)
index 0000000..2148536
--- /dev/null
@@ -0,0 +1 @@
+Fixed crash due to improperly initialized static :exc:`MemoryError` in subinterpreter.
index f376ff24386a3792a7471853a075973781aa9575..e3217c922eeba22aff463758a7986976a3c30588 100644 (file)
@@ -3701,10 +3701,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();
     }