add upstream patch to solve Python GC crash during gobject deallocation
Acked by J5 on IRC
This commit is contained in:
parent
f25dda9845
commit
bafa5fa3af
87
PyGObject-deallocation-GC-crash.patch
Normal file
87
PyGObject-deallocation-GC-crash.patch
Normal file
@ -0,0 +1,87 @@
|
||||
From 92aca4416a7930e5870b8d1a4016bae8140462ee Mon Sep 17 00:00:00 2001
|
||||
From: Daniel Drake <dsd@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
|
||||
|
||||
@ -12,7 +12,7 @@
|
||||
|
||||
Name: pygobject2
|
||||
Version: 2.28.4
|
||||
Release: 2%{?dist}
|
||||
Release: 3%{?dist}
|
||||
License: LGPLv2+
|
||||
Group: Development/Languages
|
||||
Summary: Python 2 bindings for GObject
|
||||
@ -21,6 +21,11 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-root
|
||||
#VCS: git:git://git.gnome.org/pygobject
|
||||
Source: http://ftp.gnome.org/pub/GNOME/sources/pygobject/2.28/pygobject-%{version}.tar.bz2
|
||||
|
||||
### Patches ###
|
||||
|
||||
# fixes Sugar crashes, already upstream
|
||||
Patch0: PyGObject-deallocation-GC-crash.patch
|
||||
|
||||
### Build Dependencies ###
|
||||
|
||||
BuildRequires: glib2-devel >= %{glib2_version}
|
||||
@ -90,6 +95,7 @@ for use in Python 3 programs.
|
||||
|
||||
%prep
|
||||
%setup -q -n pygobject-%{version}
|
||||
%patch0 -p1 -b .dealloc-gc
|
||||
|
||||
%if 0%{?with_python3}
|
||||
rm -rf %{py3dir}
|
||||
@ -191,6 +197,9 @@ rm examples/Makefile*
|
||||
%endif # with_python3
|
||||
|
||||
%changelog
|
||||
* Mon Jun 06 2011 Daniel Drake <dsd@laptop.org> - 2.28.4-3
|
||||
- add upstream patch to solve Python GC crash during gobject deallocation
|
||||
|
||||
* Thu Apr 21 2011 John (J5) Palmieri <johnp@redhat.com> - 2.28.4-2
|
||||
- require gobject-introspection version 0.10.8
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user