@@ -158,11 +158,16 @@ _PyDebug_PrintTotalRefs(void) {
158158 Do not call them otherwise, they do not initialize the object! */
159159
160160#ifdef Py_TRACE_REFS
161- /* Head of circular doubly-linked list of all objects. These are linked
162- * together via the _ob_prev and _ob_next members of a PyObject, which
163- * exist only in a Py_TRACE_REFS build.
164- */
165- static PyObject refchain = {& refchain , & refchain };
161+
162+ #define REFCHAIN (interp ) &interp->object_state.refchain
163+
164+ static inline void
165+ init_refchain (PyInterpreterState * interp )
166+ {
167+ PyObject * refchain = REFCHAIN (interp );
168+ refchain -> _ob_prev = refchain ;
169+ refchain -> _ob_next = refchain ;
170+ }
166171
167172/* Insert op at the front of the list of all objects. If force is true,
168173 * op is added even if _ob_prev and _ob_next are non-NULL already. If
@@ -187,10 +192,11 @@ _Py_AddToAllObjects(PyObject *op, int force)
187192 }
188193#endif
189194 if (force || op -> _ob_prev == NULL ) {
190- op -> _ob_next = refchain ._ob_next ;
191- op -> _ob_prev = & refchain ;
192- refchain ._ob_next -> _ob_prev = op ;
193- refchain ._ob_next = op ;
195+ PyObject * refchain = REFCHAIN (_PyInterpreterState_GET ());
196+ op -> _ob_next = refchain -> _ob_next ;
197+ op -> _ob_prev = refchain ;
198+ refchain -> _ob_next -> _ob_prev = op ;
199+ refchain -> _ob_next = op ;
194200 }
195201}
196202#endif /* Py_TRACE_REFS */
@@ -1998,6 +2004,18 @@ PyObject _Py_NotImplementedStruct = {
19982004 & _PyNotImplemented_Type
19992005};
20002006
2007+
2008+ void
2009+ _PyObject_InitState (PyInterpreterState * interp )
2010+ {
2011+ #ifdef Py_TRACE_REFS
2012+ if (!_Py_IsMainInterpreter (interp )) {
2013+ init_refchain (interp );
2014+ }
2015+ #endif
2016+ }
2017+
2018+
20012019extern PyTypeObject _Py_GenericAliasIterType ;
20022020extern PyTypeObject _PyMemoryIter_Type ;
20032021extern PyTypeObject _PyLineIterator ;
@@ -2206,20 +2224,21 @@ _Py_ForgetReference(PyObject *op)
22062224 _PyObject_ASSERT_FAILED_MSG (op , "negative refcnt" );
22072225 }
22082226
2209- if (op == & refchain ||
2227+ PyObject * refchain = REFCHAIN (_PyInterpreterState_GET ());
2228+ if (op == refchain ||
22102229 op -> _ob_prev -> _ob_next != op || op -> _ob_next -> _ob_prev != op )
22112230 {
22122231 _PyObject_ASSERT_FAILED_MSG (op , "invalid object chain" );
22132232 }
22142233
22152234#ifdef SLOW_UNREF_CHECK
22162235 PyObject * p ;
2217- for (p = refchain . _ob_next ; p != & refchain ; p = p -> _ob_next ) {
2236+ for (p = refchain -> _ob_next ; p != refchain ; p = p -> _ob_next ) {
22182237 if (p == op ) {
22192238 break ;
22202239 }
22212240 }
2222- if (p == & refchain ) {
2241+ if (p == refchain ) {
22232242 /* Not found */
22242243 _PyObject_ASSERT_FAILED_MSG (op ,
22252244 "object not found in the objects list" );
@@ -2235,11 +2254,15 @@ _Py_ForgetReference(PyObject *op)
22352254 * interpreter must be in a healthy state.
22362255 */
22372256void
2238- _Py_PrintReferences (FILE * fp )
2257+ _Py_PrintReferences (PyInterpreterState * interp , FILE * fp )
22392258{
22402259 PyObject * op ;
2260+ if (interp == NULL ) {
2261+ interp = _PyInterpreterState_Main ();
2262+ }
22412263 fprintf (fp , "Remaining objects:\n" );
2242- for (op = refchain ._ob_next ; op != & refchain ; op = op -> _ob_next ) {
2264+ PyObject * refchain = REFCHAIN (interp );
2265+ for (op = refchain -> _ob_next ; op != refchain ; op = op -> _ob_next ) {
22432266 fprintf (fp , "%p [%zd] " , (void * )op , Py_REFCNT (op ));
22442267 if (PyObject_Print (op , fp , 0 ) != 0 ) {
22452268 PyErr_Clear ();
@@ -2251,34 +2274,42 @@ _Py_PrintReferences(FILE *fp)
22512274/* Print the addresses of all live objects. Unlike _Py_PrintReferences, this
22522275 * doesn't make any calls to the Python C API, so is always safe to call.
22532276 */
2277+ // XXX This function is not safe to use if the interpreter has been
2278+ // freed or is in an unhealthy state (e.g. late in finalization).
2279+ // The call in Py_FinalizeEx() is okay since the main interpreter
2280+ // is statically allocated.
22542281void
2255- _Py_PrintReferenceAddresses (FILE * fp )
2282+ _Py_PrintReferenceAddresses (PyInterpreterState * interp , FILE * fp )
22562283{
22572284 PyObject * op ;
2285+ PyObject * refchain = REFCHAIN (interp );
22582286 fprintf (fp , "Remaining object addresses:\n" );
2259- for (op = refchain . _ob_next ; op != & refchain ; op = op -> _ob_next )
2287+ for (op = refchain -> _ob_next ; op != refchain ; op = op -> _ob_next )
22602288 fprintf (fp , "%p [%zd] %s\n" , (void * )op ,
22612289 Py_REFCNT (op ), Py_TYPE (op )-> tp_name );
22622290}
22632291
2292+ /* The implementation of sys.getobjects(). */
22642293PyObject *
22652294_Py_GetObjects (PyObject * self , PyObject * args )
22662295{
22672296 int i , n ;
22682297 PyObject * t = NULL ;
22692298 PyObject * res , * op ;
2299+ PyInterpreterState * interp = _PyInterpreterState_GET ();
22702300
22712301 if (!PyArg_ParseTuple (args , "i|O" , & n , & t ))
22722302 return NULL ;
2273- op = refchain ._ob_next ;
2303+ PyObject * refchain = REFCHAIN (interp );
2304+ op = refchain -> _ob_next ;
22742305 res = PyList_New (0 );
22752306 if (res == NULL )
22762307 return NULL ;
2277- for (i = 0 ; (n == 0 || i < n ) && op != & refchain ; i ++ ) {
2308+ for (i = 0 ; (n == 0 || i < n ) && op != refchain ; i ++ ) {
22782309 while (op == self || op == args || op == res || op == t ||
22792310 (t != NULL && !Py_IS_TYPE (op , (PyTypeObject * ) t ))) {
22802311 op = op -> _ob_next ;
2281- if (op == & refchain )
2312+ if (op == refchain )
22822313 return res ;
22832314 }
22842315 if (PyList_Append (res , op ) < 0 ) {
@@ -2290,7 +2321,9 @@ _Py_GetObjects(PyObject *self, PyObject *args)
22902321 return res ;
22912322}
22922323
2293- #endif
2324+ #undef REFCHAIN
2325+
2326+ #endif /* Py_TRACE_REFS */
22942327
22952328
22962329/* Hack to force loading of abstract.o */
0 commit comments