[pygobject2/f14] add upstream patch to solve Python GC crash during gobject deallocation

Daniel Drake dsd at fedoraproject.org
Mon Jun 6 16:02:53 UTC 2011


commit 82a7b7558d0049c2ef39b6106a461cc8a3cf4f6d
Author: Daniel Drake <dsd at laptop.org>
Date:   Mon Jun 6 16:39:03 2011 +0100

    add upstream patch to solve Python GC crash during gobject deallocation
    
    Acked by J5 on IRC

 PyGObject-deallocation-GC-crash.patch |   87 +++++++++++++++++++++++++++++++++
 pygobject2.spec                       |   11 ++++-
 2 files changed, 97 insertions(+), 1 deletions(-)
---
diff --git a/PyGObject-deallocation-GC-crash.patch b/PyGObject-deallocation-GC-crash.patch
new file mode 100644
index 0000000..800694b
--- /dev/null
+++ b/PyGObject-deallocation-GC-crash.patch
@@ -0,0 +1,87 @@
+From 92aca4416a7930e5870b8d1a4016bae8140462ee Mon Sep 17 00:00:00 2001
+From: Daniel Drake <dsd at laptop.org>
+Date: Fri, 3 Jun 2011 16:59:15 +0100
+Subject: [PATCH] Fix GC-related crash during PyGObject deallocation
+
+Python-2.7.1's GC source has the following comment:
+
+        /* Python's cyclic gc should never see an incoming refcount
+         * of 0:  if something decref'ed to 0, it should have been
+         * deallocated immediately at that time.
+         * Possible cause (if the assert triggers):  a tp_dealloc
+         * routine left a gc-aware object tracked during its teardown
+         * phase, and did something-- or allowed something to happen --
+         * that called back into Python.  gc can trigger then, and may
+         * see the still-tracked dying object.  Before this assert
+         * was added, such mistakes went on to allow gc to try to
+         * delete the object again.  In a debug build, that caused
+         * a mysterious segfault, when _Py_ForgetReference tried
+         * to remove the object from the doubly-linked list of all
+         * objects a second time.  In a release build, an actual
+         * double deallocation occurred, which leads to corruption
+         * of the allocator's internal bookkeeping pointers.  That's
+         * so serious that maybe this should be a release-build
+         * check instead of an assert?
+         */
+
+As shown in a backtrace at
+https://bugzilla.redhat.com/show_bug.cgi?id=640972 , pygobject is making
+this exact mistake. Before untracking its object, pygobject_dealloc
+calls PyObject_ClearWeakRefs() which can call back into python, create
+new allocations, and trigger the GC.
+
+This is causing Sugar (based on pygobject2 + pygtk2 static bindings) to
+crash on a regular basis while interacting with widgets or launching
+applications.
+
+Fix this by untracking the object early. Also fix the same issue spotted
+in the GSource wrapper.
+
+Thanks to Bernie Innocenti for initial diagnosis.
+---
+ glib/pygsource.c    |    6 ++++--
+ gobject/pygobject.c |    8 +++++++-
+ 2 files changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/glib/pygsource.c b/glib/pygsource.c
+index 684711e..d0176ab 100644
+--- a/glib/pygsource.c
++++ b/glib/pygsource.c
+@@ -387,10 +387,12 @@ pyg_source_clear(PyGSource *self)
+ static void
+ pyg_source_dealloc(PyGSource *self)
+ {
+-    PyObject_ClearWeakRefs((PyObject *)self);
+-
++    /* Must be done first, so that there is no chance of Python's GC being
++     * called while tracking this half-deallocated object */
+     PyObject_GC_UnTrack((PyObject *)self);
+ 
++    PyObject_ClearWeakRefs((PyObject *)self);
++
+     pyg_source_clear(self);
+ 
+     PyObject_GC_Del(self);
+diff --git a/gobject/pygobject.c b/gobject/pygobject.c
+index 0faf221..3193890 100644
+--- a/gobject/pygobject.c
++++ b/gobject/pygobject.c
+@@ -1028,8 +1028,14 @@ PYGLIB_DEFINE_TYPE("gobject.GObject", PyGObject_Type, PyGObject);
+ static void
+ pygobject_dealloc(PyGObject *self)
+ {
+-    PyObject_ClearWeakRefs((PyObject *)self);
++    /* Untrack must be done first. This is because followup calls such as
++     * ClearWeakRefs could call into Python and cause new allocations to
++     * happen, which could in turn could trigger the garbage collector,
++     * which would then get confused as it is tracking this half-deallocated
++     * object. */
+     PyObject_GC_UnTrack((PyObject *)self);
++
++    PyObject_ClearWeakRefs((PyObject *)self);
+       /* this forces inst_data->type to be updated, which could prove
+        * important if a new wrapper has to be created and it is of a
+        * unregistered type */
+-- 
+1.7.5.2
+
diff --git a/pygobject2.spec b/pygobject2.spec
index 5d01e79..70c6459 100644
--- a/pygobject2.spec
+++ b/pygobject2.spec
@@ -7,7 +7,7 @@
 
 Name: pygobject2
 Version: 2.21.5
-Release: 3%{?dist}
+Release: 4%{?dist}
 License: LGPLv2+
 Group: Development/Languages
 Summary: Python bindings for GObject
@@ -16,6 +16,11 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-root
 #VCS: git:git://git.gnome.org/pygobject
 Source: http://ftp.gnome.org/pub/GNOME/sources/pygobject/2.21/pygobject-%{version}.tar.bz2
 
+### Patches ###
+
+# fixes Sugar crashes, already upstream
+Patch0: PyGObject-deallocation-GC-crash.patch
+
 ### Build Dependencies ###
 
 BuildRequires: glib2-devel >= %{glib2_version}
@@ -64,6 +69,7 @@ This package contains documentation files for %{name}.
 
 %prep
 %setup -q -n pygobject-%{version}
+%patch0 -p1 -b .dealloc-gc
 
 %build
 %configure
@@ -109,6 +115,9 @@ rm examples/Makefile*
 %{_datadir}/pygobject/xsl
 
 %changelog
+* Mon Jun 06 2011 Daniel Drake <dsd at laptop.org> - 2.21.5-4
+- add upstream patch to solve Python GC crash during gobject deallocation
+
 * Wed Jul 21 2010 David Malcolm <dmalcolm at redhat.com> - 2.21.5-3
 - Rebuilt for https://fedoraproject.org/wiki/Features/Python_2.7/MassRebuild
 


More information about the scm-commits mailing list