]> granicus.if.org Git - python/commitdiff
When Py_TRACE_REFS is defined, a list of all live objects is maintained in
authorTim Peters <tim.peters@gmail.com>
Sun, 23 Mar 2003 02:51:01 +0000 (02:51 +0000)
committerTim Peters <tim.peters@gmail.com>
Sun, 23 Mar 2003 02:51:01 +0000 (02:51 +0000)
a doubly-linked list, exposed by sys.getobjects().  Unfortunately, it's not
really all live objects, and it seems my fate to bump into programs where
sys.gettotalrefcount() keeps going up but where the reference leaks aren't
accounted for by anything in the list of all objects.

This patch helps a little:  if COUNT_ALLOCS is also defined, from now on
type objects will also appear in this list, provided at least one object
of a type has been allocated.

Misc/SpecialBuilds.txt
Objects/object.c

index a4226c92ae6742a27beeb45fabb75d08155d7246..a3d35586f4d2bc367ab00f68bbaefe874fc93262 100644 (file)
@@ -34,10 +34,14 @@ Py_TRACE_REFS                                             introduced in 1.4
 
 Turn on heavy reference debugging.  This is major surgery.  Every PyObject
 grows two more pointers, to maintain a doubly-linked list of all live
-heap-allocated objects (note that, e.g., most builtin type objects are not
-in this list, as they're statically allocated).  Note that because the
-fundamental PyObject layout changes, Python modules compiled with
-Py_TRACE_REFS are incompatible with modules compiled without it.
+heap-allocated objects.  Most builtin type objects are not in this list,
+as they're statically allocated.  Starting in Python 2.3, if COUNT_ALLOCS
+(see below) is also defined, a static type object T does appear in this
+list if at least one object of type T has been created.
+
+Note that because the fundamental PyObject layout changes, Python modules
+compiled with Py_TRACE_REFS are incompatible with modules compiled without
+it.
 
 Py_TRACE_REFS implies Py_REF_DEBUG.
 
@@ -171,6 +175,11 @@ because of this; this was fixed in 2.2.2.  Use of COUNT_ALLOCS makes
 all heap-allocated type objects immortal, except for those for which no
 object of that type is ever allocated.
 
+Starting with Python 2.3, If Py_TRACE_REFS is also defined, COUNT_ALLOCS
+arranges to ensure that the type object for each allocated object
+appears in the doubly-linked list of all objects maintained by
+Py_TRACE_REFS.
+
 Special gimmicks:
 
 sys.getcounts()
index 9ce3de7e06da0176a2cc7a40e1ccb64aa06ddc46..2332df837d7f19073e6160626d5fcc5a6241b8f1 100644 (file)
@@ -17,6 +17,11 @@ int Py_DivisionWarningFlag;
    These are used by the individual routines for object creation.
    Do not call them otherwise, they do not initialize the object! */
 
+#ifdef Py_TRACE_REFS
+/* Head of doubly-linked list of all objects. */
+static PyObject refchain = {&refchain, &refchain};
+#endif
+
 #ifdef COUNT_ALLOCS
 static PyTypeObject *type_list;
 extern int tuple_zero_allocs, fast_tuple_allocs;
@@ -84,6 +89,16 @@ inc_count(PyTypeObject *tp)
                 */
                Py_INCREF(tp);
                type_list = tp;
+#ifdef Py_REF_DEBUG
+               /* Also insert in the doubly-linked list of all objects. */
+               if (tp->_ob_next == NULL) {
+                       PyObject *op = (PyObject *)tp;
+                       op->_ob_next = refchain._ob_next;
+                       op->_ob_prev = &refchain;
+                       refchain._ob_next->_ob_prev = op;
+                       refchain._ob_next = op;
+               }
+#endif
        }
        tp->tp_allocs++;
        if (tp->tp_allocs - tp->tp_frees > tp->tp_maxalloc)
@@ -1936,8 +1951,6 @@ _Py_ReadyTypes(void)
 
 #ifdef Py_TRACE_REFS
 
-static PyObject refchain = {&refchain, &refchain};
-
 void
 _Py_NewReference(PyObject *op)
 {