@@ -158,11 +158,8 @@ _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
166163
167164/* Insert op at the front of the list of all objects. If force is true,
168165 * op is added even if _ob_prev and _ob_next are non-NULL already. If
@@ -187,10 +184,11 @@ _Py_AddToAllObjects(PyObject *op, int force)
187184 }
188185#endif
189186 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 ;
187+ PyObject * refchain = REFCHAIN (_PyInterpreterState_GET ());
188+ op -> _ob_next = refchain -> _ob_next ;
189+ op -> _ob_prev = refchain ;
190+ refchain -> _ob_next -> _ob_prev = op ;
191+ refchain -> _ob_next = op ;
194192 }
195193}
196194#endif /* Py_TRACE_REFS */
@@ -2206,20 +2204,21 @@ _Py_ForgetReference(PyObject *op)
22062204 _PyObject_ASSERT_FAILED_MSG (op , "negative refcnt" );
22072205 }
22082206
2209- if (op == & refchain ||
2207+ PyObject * refchain = REFCHAIN (_PyInterpreterState_GET ());
2208+ if (op == refchain ||
22102209 op -> _ob_prev -> _ob_next != op || op -> _ob_next -> _ob_prev != op )
22112210 {
22122211 _PyObject_ASSERT_FAILED_MSG (op , "invalid object chain" );
22132212 }
22142213
22152214#ifdef SLOW_UNREF_CHECK
22162215 PyObject * p ;
2217- for (p = refchain . _ob_next ; p != & refchain ; p = p -> _ob_next ) {
2216+ for (p = refchain -> _ob_next ; p != refchain ; p = p -> _ob_next ) {
22182217 if (p == op ) {
22192218 break ;
22202219 }
22212220 }
2222- if (p == & refchain ) {
2221+ if (p == refchain ) {
22232222 /* Not found */
22242223 _PyObject_ASSERT_FAILED_MSG (op ,
22252224 "object not found in the objects list" );
@@ -2235,11 +2234,15 @@ _Py_ForgetReference(PyObject *op)
22352234 * interpreter must be in a healthy state.
22362235 */
22372236void
2238- _Py_PrintReferences (FILE * fp )
2237+ _Py_PrintReferences (PyInterpreterState * interp , FILE * fp )
22392238{
22402239 PyObject * op ;
2240+ if (interp == NULL ) {
2241+ interp = _PyInterpreterState_Main ();
2242+ }
22412243 fprintf (fp , "Remaining objects:\n" );
2242- for (op = refchain ._ob_next ; op != & refchain ; op = op -> _ob_next ) {
2244+ PyObject * refchain = REFCHAIN (interp );
2245+ for (op = refchain -> _ob_next ; op != refchain ; op = op -> _ob_next ) {
22432246 fprintf (fp , "%p [%zd] " , (void * )op , Py_REFCNT (op ));
22442247 if (PyObject_Print (op , fp , 0 ) != 0 ) {
22452248 PyErr_Clear ();
@@ -2251,34 +2254,42 @@ _Py_PrintReferences(FILE *fp)
22512254/* Print the addresses of all live objects. Unlike _Py_PrintReferences, this
22522255 * doesn't make any calls to the Python C API, so is always safe to call.
22532256 */
2257+ // XXX This function is not safe to use if the interpreter has been
2258+ // freed or is in an unhealthy state (e.g. late in finalization).
2259+ // The call in Py_FinalizeEx() is okay since the main interpreter
2260+ // is statically allocated.
22542261void
2255- _Py_PrintReferenceAddresses (FILE * fp )
2262+ _Py_PrintReferenceAddresses (PyInterpreterState * interp , FILE * fp )
22562263{
22572264 PyObject * op ;
2265+ PyObject * refchain = REFCHAIN (interp );
22582266 fprintf (fp , "Remaining object addresses:\n" );
2259- for (op = refchain . _ob_next ; op != & refchain ; op = op -> _ob_next )
2267+ for (op = refchain -> _ob_next ; op != refchain ; op = op -> _ob_next )
22602268 fprintf (fp , "%p [%zd] %s\n" , (void * )op ,
22612269 Py_REFCNT (op ), Py_TYPE (op )-> tp_name );
22622270}
22632271
2272+ /* The implementation of sys.getobjects(). */
22642273PyObject *
22652274_Py_GetObjects (PyObject * self , PyObject * args )
22662275{
22672276 int i , n ;
22682277 PyObject * t = NULL ;
22692278 PyObject * res , * op ;
2279+ PyInterpreterState * interp = _PyInterpreterState_GET ();
22702280
22712281 if (!PyArg_ParseTuple (args , "i|O" , & n , & t ))
22722282 return NULL ;
2273- op = refchain ._ob_next ;
2283+ PyObject * refchain = REFCHAIN (interp );
2284+ op = refchain -> _ob_next ;
22742285 res = PyList_New (0 );
22752286 if (res == NULL )
22762287 return NULL ;
2277- for (i = 0 ; (n == 0 || i < n ) && op != & refchain ; i ++ ) {
2288+ for (i = 0 ; (n == 0 || i < n ) && op != refchain ; i ++ ) {
22782289 while (op == self || op == args || op == res || op == t ||
22792290 (t != NULL && !Py_IS_TYPE (op , (PyTypeObject * ) t ))) {
22802291 op = op -> _ob_next ;
2281- if (op == & refchain )
2292+ if (op == refchain )
22822293 return res ;
22832294 }
22842295 if (PyList_Append (res , op ) < 0 ) {
@@ -2290,6 +2301,8 @@ _Py_GetObjects(PyObject *self, PyObject *args)
22902301 return res ;
22912302}
22922303
2304+ #undef REFCHAIN
2305+
22932306#endif
22942307
22952308
0 commit comments