From 430632d6f710c99879c5d1736f3b40ea09b11c4d Mon Sep 17 00:00:00 2001 From: Eric Snow Date: Mon, 7 Aug 2023 13:14:56 -0600 Subject: [PATCH] gh-107630: Initialize Each Interpreter's refchain Properly (gh-107733) This finishes fixing the crashes in Py_TRACE_REFS builds. We missed this part in gh-107567. --- Include/internal/pycore_object.h | 1 + Objects/object.c | 22 +++++++++++++++++++++- Python/pylifecycle.c | 2 ++ Python/pystate.c | 1 + 4 files changed, 25 insertions(+), 1 deletion(-) diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h index 76b3cd69cbf..7cdf64bcdac 100644 --- a/Include/internal/pycore_object.h +++ b/Include/internal/pycore_object.h @@ -173,6 +173,7 @@ _PyType_HasFeature(PyTypeObject *type, unsigned long feature) { extern void _PyType_InitCache(PyInterpreterState *interp); +extern void _PyObject_InitState(PyInterpreterState *interp); /* Inline functions trading binary compatibility for speed: _PyObject_Init() is the fast version of PyObject_Init(), and diff --git a/Objects/object.c b/Objects/object.c index c4413a00ede..d1154eb344f 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -162,6 +162,14 @@ _PyDebug_PrintTotalRefs(void) { #define REFCHAIN(interp) &interp->object_state.refchain +static inline void +init_refchain(PyInterpreterState *interp) +{ + PyObject *refchain = REFCHAIN(interp); + refchain->_ob_prev = refchain; + refchain->_ob_next = refchain; +} + /* Insert op at the front of the list of all objects. If force is true, * op is added even if _ob_prev and _ob_next are non-NULL already. If * force is false amd _ob_prev or _ob_next are non-NULL, do nothing. @@ -2019,6 +2027,18 @@ PyObject _Py_NotImplementedStruct = { &_PyNotImplemented_Type }; + +void +_PyObject_InitState(PyInterpreterState *interp) +{ +#ifdef Py_TRACE_REFS + if (!_Py_IsMainInterpreter(interp)) { + init_refchain(interp); + } +#endif +} + + extern PyTypeObject _Py_GenericAliasIterType; extern PyTypeObject _PyMemoryIter_Type; extern PyTypeObject _PyLineIterator; @@ -2326,7 +2346,7 @@ _Py_GetObjects(PyObject *self, PyObject *args) #undef REFCHAIN -#endif +#endif /* Py_TRACE_REFS */ /* Hack to force loading of abstract.o */ diff --git a/Python/pylifecycle.c b/Python/pylifecycle.c index 7a17f92b550..0de3abf9407 100644 --- a/Python/pylifecycle.c +++ b/Python/pylifecycle.c @@ -2075,6 +2075,8 @@ new_interpreter(PyThreadState **tstate_p, const PyInterpreterConfig *config) } has_gil = 1; + /* No objects have been created yet. */ + status = pycore_interp_init(tstate); if (_PyStatus_EXCEPTION(status)) { goto error; diff --git a/Python/pystate.c b/Python/pystate.c index a1864cc3249..3a05cb0fa79 100644 --- a/Python/pystate.c +++ b/Python/pystate.c @@ -674,6 +674,7 @@ init_interpreter(PyInterpreterState *interp, _obmalloc_pools_INIT(interp->obmalloc.pools); memcpy(&interp->obmalloc.pools.used, temp, sizeof(temp)); } + _PyObject_InitState(interp); _PyEval_InitState(interp, pending_lock); _PyGC_InitState(&interp->gc);