summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Peters <tim.peters@gmail.com>2003-04-17 19:52:29 (GMT)
committerTim Peters <tim.peters@gmail.com>2003-04-17 19:52:29 (GMT)
commit269b2a6797a11958929a5c1102dd1dd67d29e411 (patch)
tree37287664d133867925f963734231c9a08af052f6
parenta4ea603b055533e71920a088acb1c106e4895dbd (diff)
downloadcpython-269b2a6797a11958929a5c1102dd1dd67d29e411.zip
cpython-269b2a6797a11958929a5c1102dd1dd67d29e411.tar.gz
cpython-269b2a6797a11958929a5c1102dd1dd67d29e411.tar.bz2
_Py_PrintReferences(): Changed to print object address at start of each
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().
-rw-r--r--Include/object.h1
-rw-r--r--Objects/object.c17
-rw-r--r--Python/pythonrun.c11
3 files changed, 26 insertions, 3 deletions
diff --git a/Include/object.h b/Include/object.h
index 3ac7538..3c7264f 100644
--- a/Include/object.h
+++ b/Include/object.h
@@ -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
diff --git a/Objects/object.c b/Objects/object.c
index c876219..49b9839 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -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)
{
diff --git a/Python/pythonrun.c b/Python/pythonrun.c
index 4cfb664..0a9a637 100644
--- a/Python/pythonrun.c
+++ b/Python/pythonrun.c
@@ -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();