Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 269b2a6

Browse files
committed
_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().
1 parent a4ea603 commit 269b2a6

3 files changed

Lines changed: 26 additions & 3 deletions

File tree

Include/object.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -582,6 +582,7 @@ PyAPI_FUNC(void) _Py_NewReference(PyObject *);
582582
PyAPI_FUNC(void) _Py_ForgetReference(PyObject *);
583583
PyAPI_FUNC(void) _Py_Dealloc(PyObject *);
584584
PyAPI_FUNC(void) _Py_PrintReferences(FILE *);
585+
PyAPI_FUNC(void) _Py_PrintReferenceAddresses(FILE *);
585586
PyAPI_FUNC(void) _Py_AddToAllObjects(PyObject *, int force);
586587

587588
#else

Objects/object.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2022,19 +2022,34 @@ _Py_Dealloc(PyObject *op)
20222022
(*dealloc)(op);
20232023
}
20242024

2025+
/* Print all live objects. Because PyObject_Print is called, the
2026+
* interpreter must be in a healthy state.
2027+
*/
20252028
void
20262029
_Py_PrintReferences(FILE *fp)
20272030
{
20282031
PyObject *op;
20292032
fprintf(fp, "Remaining objects:\n");
20302033
for (op = refchain._ob_next; op != &refchain; op = op->_ob_next) {
2031-
fprintf(fp, "[%d] ", op->ob_refcnt);
2034+
fprintf(fp, "%p [%d] ", op, op->ob_refcnt);
20322035
if (PyObject_Print(op, fp, 0) != 0)
20332036
PyErr_Clear();
20342037
putc('\n', fp);
20352038
}
20362039
}
20372040

2041+
/* Print the addresses of all live objects. Unlike _Py_PrintReferences, this
2042+
* doesn't make any calls to the Python C API, so is always safe to call.
2043+
*/
2044+
void
2045+
_Py_PrintReferenceAddresses(FILE *fp)
2046+
{
2047+
PyObject *op;
2048+
fprintf(fp, "Remaining object addresses:\n");
2049+
for (op = refchain._ob_next; op != &refchain; op = op->_ob_next)
2050+
fprintf(fp, "%p [%d]\n", op, op->ob_refcnt);
2051+
}
2052+
20382053
PyObject *
20392054
_Py_GetObjects(PyObject *self, PyObject *args)
20402055
{

Python/pythonrun.c

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,9 +284,8 @@ Py_Finalize(void)
284284
* Alas, a lot of stuff may still be alive now that will be cleaned
285285
* up later.
286286
*/
287-
if (Py_GETENV("PYTHONDUMPREFS")) {
287+
if (Py_GETENV("PYTHONDUMPREFS"))
288288
_Py_PrintReferences(stderr);
289-
}
290289
#endif /* Py_TRACE_REFS */
291290

292291
/* Now we decref the exception classes. After this point nothing
@@ -325,6 +324,14 @@ Py_Finalize(void)
325324

326325
PyGrammar_RemoveAccelerators(&_PyParser_Grammar);
327326

327+
#ifdef Py_TRACE_REFS
328+
/* Display addresses (& refcnts) of all objects still alive.
329+
* An address can be used to find the repr of the object, printed
330+
* above by _Py_PrintReferences.
331+
*/
332+
if (Py_GETENV("PYTHONDUMPREFS"))
333+
_Py_PrintReferenceAddresses(stderr);
334+
#endif /* Py_TRACE_REFS */
328335
#ifdef PYMALLOC_DEBUG
329336
if (Py_GETENV("PYTHONMALLOCSTATS"))
330337
_PyObject_DebugMallocStats();

0 commit comments

Comments
 (0)