]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
SF bug 578752: COUNT_ALLOCS vs heap types
authorTim Peters <tim.peters@gmail.com>
Mon, 8 Jul 2002 22:30:52 +0000 (22:30 +0000)
committerTim Peters <tim.peters@gmail.com>
Mon, 8 Jul 2002 22:30:52 +0000 (22:30 +0000)
Repair segfaults and infinite loops in COUNT_ALLOCS builds in the
presence of new-style (heap-allocated) classes/types.

Note:  test_gc fails in a COUNT_ALLOCS build now, because it expects
a new-style class to get garbage collected.

Misc/NEWS
Objects/object.c

index 205a5f625ffa30a7acbdea5bfdaee1f1aadbccf6..1e256cbd3d185ec6ea30af6ebd909fcaeb55b88a 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -45,9 +45,17 @@ Library
   custom metaclasses the same way it treats instances of type 'type'
   [SF patch 560794].
 
+Build
 
-C API
+- A bug was fixed that could cause COUNT_ALLOCS builds to segfault, or
+  get into infinite loops, when a new-style class got garbage-collected.
+  Unfortunately, to avoid this, the way COUNT_ALLOCS works requires
+  that new-style classes be immortal in COUNT_ALLOCS builds.  Note that
+  COUNT_ALLOCS is not enabled by default, in either release or debug
+  builds, and that new-style classes are immortal only in COUNT_ALLOCS
+  builds.  SourceForge bug 578752.
 
+C API
 
 Windows
 
index 510ea736758df7c94af0f66c87366bff05d456e8..27efb4ad24c9a38c3066b65ab9b0463e433f3d51 100644 (file)
@@ -79,6 +79,15 @@ inc_count(PyTypeObject *tp)
                if (tp->tp_next != NULL) /* sanity check */
                        Py_FatalError("XXX inc_count sanity check");
                tp->tp_next = type_list;
+               /* Note that as of Python 2.2, heap-allocated type objects
+                * can go away, but this code requires that they stay alive
+                * until program exit.  That's why we're careful with
+                * refcounts here.  type_list gets a new reference to tp,
+                * while ownership of the reference type_list used to hold
+                * (if any) was transferred to tp->tp_next in the line above.
+                * tp is thus effectively immortal after this.
+                */
+               Py_INCREF(tp);
                type_list = tp;
        }
        tp->tp_allocs++;