@@ -159,11 +159,8 @@ _PyDebug_PrintTotalRefs(void) {
159159 Do not call them otherwise, they do not initialize the object! */
160160
161161#ifdef Py_TRACE_REFS
162- /* Head of circular doubly-linked list of all objects. These are linked
163- * together via the _ob_prev and _ob_next members of a PyObject, which
164- * exist only in a Py_TRACE_REFS build.
165- */
166- static PyObject refchain = {& refchain , & refchain };
162+
163+ #define REFCHAIN (interp ) &interp->object_state.refchain
167164
168165/* Insert op at the front of the list of all objects. If force is true,
169166 * op is added even if _ob_prev and _ob_next are non-NULL already. If
@@ -188,10 +185,11 @@ _Py_AddToAllObjects(PyObject *op, int force)
188185 }
189186#endif
190187 if (force || op -> _ob_prev == NULL ) {
191- op -> _ob_next = refchain ._ob_next ;
192- op -> _ob_prev = & refchain ;
193- refchain ._ob_next -> _ob_prev = op ;
194- refchain ._ob_next = op ;
188+ PyObject * refchain = REFCHAIN (_PyInterpreterState_GET ());
189+ op -> _ob_next = refchain -> _ob_next ;
190+ op -> _ob_prev = refchain ;
191+ refchain -> _ob_next -> _ob_prev = op ;
192+ refchain -> _ob_next = op ;
195193 }
196194}
197195#endif /* Py_TRACE_REFS */
@@ -2229,20 +2227,21 @@ _Py_ForgetReference(PyObject *op)
22292227 _PyObject_ASSERT_FAILED_MSG (op , "negative refcnt" );
22302228 }
22312229
2232- if (op == & refchain ||
2230+ PyObject * refchain = REFCHAIN (_PyInterpreterState_GET ());
2231+ if (op == refchain ||
22332232 op -> _ob_prev -> _ob_next != op || op -> _ob_next -> _ob_prev != op )
22342233 {
22352234 _PyObject_ASSERT_FAILED_MSG (op , "invalid object chain" );
22362235 }
22372236
22382237#ifdef SLOW_UNREF_CHECK
22392238 PyObject * p ;
2240- for (p = refchain . _ob_next ; p != & refchain ; p = p -> _ob_next ) {
2239+ for (p = refchain -> _ob_next ; p != refchain ; p = p -> _ob_next ) {
22412240 if (p == op ) {
22422241 break ;
22432242 }
22442243 }
2245- if (p == & refchain ) {
2244+ if (p == refchain ) {
22462245 /* Not found */
22472246 _PyObject_ASSERT_FAILED_MSG (op ,
22482247 "object not found in the objects list" );
@@ -2258,11 +2257,15 @@ _Py_ForgetReference(PyObject *op)
22582257 * interpreter must be in a healthy state.
22592258 */
22602259void
2261- _Py_PrintReferences (FILE * fp )
2260+ _Py_PrintReferences (PyInterpreterState * interp , FILE * fp )
22622261{
22632262 PyObject * op ;
2263+ if (interp == NULL ) {
2264+ interp = _PyInterpreterState_Main ();
2265+ }
22642266 fprintf (fp , "Remaining objects:\n" );
2265- for (op = refchain ._ob_next ; op != & refchain ; op = op -> _ob_next ) {
2267+ PyObject * refchain = REFCHAIN (interp );
2268+ for (op = refchain -> _ob_next ; op != refchain ; op = op -> _ob_next ) {
22662269 fprintf (fp , "%p [%zd] " , (void * )op , Py_REFCNT (op ));
22672270 if (PyObject_Print (op , fp , 0 ) != 0 ) {
22682271 PyErr_Clear ();
@@ -2274,34 +2277,42 @@ _Py_PrintReferences(FILE *fp)
22742277/* Print the addresses of all live objects. Unlike _Py_PrintReferences, this
22752278 * doesn't make any calls to the Python C API, so is always safe to call.
22762279 */
2280+ // XXX This function is not safe to use if the interpreter has been
2281+ // freed or is in an unhealthy state (e.g. late in finalization).
2282+ // The call in Py_FinalizeEx() is okay since the main interpreter
2283+ // is statically allocated.
22772284void
2278- _Py_PrintReferenceAddresses (FILE * fp )
2285+ _Py_PrintReferenceAddresses (PyInterpreterState * interp , FILE * fp )
22792286{
22802287 PyObject * op ;
2288+ PyObject * refchain = REFCHAIN (interp );
22812289 fprintf (fp , "Remaining object addresses:\n" );
2282- for (op = refchain . _ob_next ; op != & refchain ; op = op -> _ob_next )
2290+ for (op = refchain -> _ob_next ; op != refchain ; op = op -> _ob_next )
22832291 fprintf (fp , "%p [%zd] %s\n" , (void * )op ,
22842292 Py_REFCNT (op ), Py_TYPE (op )-> tp_name );
22852293}
22862294
2295+ /* The implementation of sys.getobjects(). */
22872296PyObject *
22882297_Py_GetObjects (PyObject * self , PyObject * args )
22892298{
22902299 int i , n ;
22912300 PyObject * t = NULL ;
22922301 PyObject * res , * op ;
2302+ PyInterpreterState * interp = _PyInterpreterState_GET ();
22932303
22942304 if (!PyArg_ParseTuple (args , "i|O" , & n , & t ))
22952305 return NULL ;
2296- op = refchain ._ob_next ;
2306+ PyObject * refchain = REFCHAIN (interp );
2307+ op = refchain -> _ob_next ;
22972308 res = PyList_New (0 );
22982309 if (res == NULL )
22992310 return NULL ;
2300- for (i = 0 ; (n == 0 || i < n ) && op != & refchain ; i ++ ) {
2311+ for (i = 0 ; (n == 0 || i < n ) && op != refchain ; i ++ ) {
23012312 while (op == self || op == args || op == res || op == t ||
23022313 (t != NULL && !Py_IS_TYPE (op , (PyTypeObject * ) t ))) {
23032314 op = op -> _ob_next ;
2304- if (op == & refchain )
2315+ if (op == refchain )
23052316 return res ;
23062317 }
23072318 if (PyList_Append (res , op ) < 0 ) {
@@ -2313,6 +2324,8 @@ _Py_GetObjects(PyObject *self, PyObject *args)
23132324 return res ;
23142325}
23152326
2327+ #undef REFCHAIN
2328+
23162329#endif
23172330
23182331
0 commit comments