Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 1 addition & 4 deletions Include/internal/pycore_interp_structs.h
Original file line number Diff line number Diff line change
Expand Up @@ -768,10 +768,7 @@ 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.
*/
// unused, kept for ABI compatibility
void *_malloced;

PyInterpreterState *next;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix memory leak in sub-interpreter creation.
15 changes: 9 additions & 6 deletions Python/pystate.c
Original file line number Diff line number Diff line change
Expand Up @@ -565,16 +565,19 @@ _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) + alignment - 1;
size_t allocsize = sizeof(PyInterpreterState) + sizeof(void *) + alignment - 1;
void *mem = PyMem_RawCalloc(1, allocsize);
if (mem == NULL) {
return NULL;
}
PyInterpreterState *interp = _Py_ALIGN_UP(mem, alignment);
assert(_Py_IS_ALIGNED(interp, alignment));
interp->_malloced = mem;
return interp;
void *ptr = _Py_ALIGN_UP((char *)mem + sizeof(void *), alignment);
((void **)ptr)[-1] = mem;
assert(_Py_IS_ALIGNED(ptr, alignment));
return ptr;
}

static void
Expand All @@ -589,7 +592,7 @@ free_interpreter(PyInterpreterState *interp)
interp->obmalloc = NULL;
}
assert(_Py_IS_ALIGNED(interp, _Alignof(PyInterpreterState)));
PyMem_RawFree(interp->_malloced);
PyMem_RawFree(((void **)interp)[-1]);
}
}

Expand Down
Loading