]> granicus.if.org Git - python/commitdiff
_Py_PrintReferences(): Changed to print object address at start of each
authorTim Peters <tim.peters@gmail.com>
Thu, 17 Apr 2003 19:52:29 +0000 (19:52 +0000)
committerTim Peters <tim.peters@gmail.com>
Thu, 17 Apr 2003 19:52:29 +0000 (19:52 +0000)
new line.

New pvt API function _Py_PrintReferenceAddresses():  Prints only the
addresses and refcnts of the live objects.  This is always safe to call,
because it has no dependence on Python's C API.

Py_Finalize():  If envar PYTHONDUMPREFS is set, call (the new)
_Py_PrintReferenceAddresses() right before dumping final pymalloc stats.
We can't print the reprs of the objects here because too much of the
interpreter has been shut down.  You need to correlate the addresses
displayed here with the object reprs printed by the earlier
PYTHONDUMPREFS call to _Py_PrintReferences().

Include/object.h
Objects/object.c
Python/pythonrun.c

index 3ac75380a204ba147ad28f63a3ba1fa159a84abc..3c7264f7977d32722d0288551d29866db0b701f6 100644 (file)
@@ -582,6 +582,7 @@ PyAPI_FUNC(void) _Py_NewReference(PyObject *);
 PyAPI_FUNC(void) _Py_ForgetReference(PyObject *);
 PyAPI_FUNC(void) _Py_Dealloc(PyObject *);
 PyAPI_FUNC(void) _Py_PrintReferences(FILE *);
+PyAPI_FUNC(void) _Py_PrintReferenceAddresses(FILE *);
 PyAPI_FUNC(void) _Py_AddToAllObjects(PyObject *, int force);
 
 #else
index c8762193094b82241d072954d977709b60b4a2bb..49b983961a59bacec64872713383c830482ff4d5 100644 (file)
@@ -2022,19 +2022,34 @@ _Py_Dealloc(PyObject *op)
        (*dealloc)(op);
 }
 
+/* Print all live objects.  Because PyObject_Print is called, the
+ * interpreter must be in a healthy state.
+ */
 void
 _Py_PrintReferences(FILE *fp)
 {
        PyObject *op;
        fprintf(fp, "Remaining objects:\n");
        for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) {
-               fprintf(fp, "[%d] ", op->ob_refcnt);
+               fprintf(fp, "%p [%d] ", op, op->ob_refcnt);
                if (PyObject_Print(op, fp, 0) != 0)
                        PyErr_Clear();
                putc('\n', fp);
        }
 }
 
+/* Print the addresses of all live objects.  Unlike _Py_PrintReferences, this
+ * doesn't make any calls to the Python C API, so is always safe to call.
+ */
+void
+_Py_PrintReferenceAddresses(FILE *fp)
+{
+       PyObject *op;
+       fprintf(fp, "Remaining object addresses:\n");
+       for (op = refchain._ob_next; op != &refchain; op = op->_ob_next)
+               fprintf(fp, "%p [%d]\n", op, op->ob_refcnt);
+}
+
 PyObject *
 _Py_GetObjects(PyObject *self, PyObject *args)
 {
index 4cfb664a27ad2b7d3d0b5295d1ab92205ccba2e8..0a9a63723c2f87cf41822f703a869747cd19de50 100644 (file)
@@ -284,9 +284,8 @@ Py_Finalize(void)
         * Alas, a lot of stuff may still be alive now that will be cleaned
         * up later.
         */
-       if (Py_GETENV("PYTHONDUMPREFS")) {
+       if (Py_GETENV("PYTHONDUMPREFS"))
                _Py_PrintReferences(stderr);
-       }
 #endif /* Py_TRACE_REFS */
 
        /* Now we decref the exception classes.  After this point nothing
@@ -325,6 +324,14 @@ Py_Finalize(void)
 
        PyGrammar_RemoveAccelerators(&_PyParser_Grammar);
 
+#ifdef Py_TRACE_REFS
+       /* Display addresses (& refcnts) of all objects still alive.
+        * An address can be used to find the repr of the object, printed
+        * above by _Py_PrintReferences.
+        */
+       if (Py_GETENV("PYTHONDUMPREFS"))
+               _Py_PrintReferenceAddresses(stderr);
+#endif /* Py_TRACE_REFS */
 #ifdef PYMALLOC_DEBUG
        if (Py_GETENV("PYTHONMALLOCSTATS"))
                _PyObject_DebugMallocStats();