summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Misc/NEWS8
-rw-r--r--Objects/object.c9
2 files changed, 17 insertions, 0 deletions
diff --git a/Misc/NEWS b/Misc/NEWS
index 2d323ea..7bc9817 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -294,6 +294,14 @@ Tools/Demos
Build
+- 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.
+
- Compiling out the cyclic garbage collector is no longer an option.
The old symbol WITH_CYCLE_GC is now ignored, and Python.h arranges
that it's always defined (for the benefit of any extension modules
diff --git a/Objects/object.c b/Objects/object.c
index 5c53908..fd069f1 100644
--- a/Objects/object.c
+++ b/Objects/object.c
@@ -74,6 +74,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++;