]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Revert "gh-140067: Fix memory leak in sub-interpreter creation (#140111)" (#140140)
authorPeter Bierma <zintensitydev@gmail.com>
Wed, 15 Oct 2025 01:46:43 +0000 (21:46 -0400)
committerGitHub <noreply@github.com>
Wed, 15 Oct 2025 01:46:43 +0000 (07:16 +0530)
This reverts commit 59547a251f7069dc6e08cb6082dd21872671e381.

Include/internal/pycore_interp_structs.h
Misc/NEWS.d/next/Core_and_Builtins/2025-10-14-17-07-37.gh-issue-140067.ID2gOm.rst [deleted file]
Python/pystate.c

index badc97808c6132a871b96bd5f601f67ee21a81e0..2124e76514f1af0a771435fe0da49980c1c254aa 100644 (file)
@@ -769,6 +769,12 @@ struct _is {
      * and should be placed at the beginning. */
     struct _ceval_state ceval;
 
+    /* This structure is carefully allocated so that it's correctly aligned
+     * to avoid undefined behaviors during LOAD and STORE. The '_malloced'
+     * field stores the allocated pointer address that will later be freed.
+     */
+    void *_malloced;
+
     PyInterpreterState *next;
 
     int64_t id;
diff --git a/Misc/NEWS.d/next/Core_and_Builtins/2025-10-14-17-07-37.gh-issue-140067.ID2gOm.rst b/Misc/NEWS.d/next/Core_and_Builtins/2025-10-14-17-07-37.gh-issue-140067.ID2gOm.rst
deleted file mode 100644 (file)
index 3c5a828..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Fix memory leak in sub-interpreter creation.
index bf6e4e56e6df87319221bc76fd7d688e533089e1..dbed609f29aa074fcf2506cf93f7dc17cd460c55 100644 (file)
@@ -457,19 +457,16 @@ _PyInterpreterState_Enable(_PyRuntimeState *runtime)
 static PyInterpreterState *
 alloc_interpreter(void)
 {
-    // Aligned allocation for PyInterpreterState.
-    // the first word of the memory block is used to store
-    // the original pointer to be used later to free the memory.
     size_t alignment = _Alignof(PyInterpreterState);
-    size_t allocsize = sizeof(PyInterpreterState) + sizeof(void *) + alignment - 1;
+    size_t allocsize = sizeof(PyInterpreterState) + alignment - 1;
     void *mem = PyMem_RawCalloc(1, allocsize);
     if (mem == NULL) {
         return NULL;
     }
-    void *ptr = _Py_ALIGN_UP((char *)mem + sizeof(void *), alignment);
-    ((void **)ptr)[-1] = mem;
-    assert(_Py_IS_ALIGNED(ptr, alignment));
-    return ptr;
+    PyInterpreterState *interp = _Py_ALIGN_UP(mem, alignment);
+    assert(_Py_IS_ALIGNED(interp, alignment));
+    interp->_malloced = mem;
+    return interp;
 }
 
 static void
@@ -484,7 +481,7 @@ free_interpreter(PyInterpreterState *interp)
             interp->obmalloc = NULL;
         }
         assert(_Py_IS_ALIGNED(interp, _Alignof(PyInterpreterState)));
-        PyMem_RawFree(((void **)interp)[-1]);
+        PyMem_RawFree(interp->_malloced);
     }
 }