[Pkg-utopia-maintainers] Bug#766762: upower: fatal memory leak on low battery

Michael Banck mbanck at debian.org
Fri Nov 28 17:02:40 UTC 2014


On Fri, Nov 28, 2014 at 04:51:25PM +0100, Michael Banck wrote:
> Debdiff is attached.

Sorry, now is.


Michael
-------------- next part --------------
diff -Nru upower-0.99.1/debian/changelog upower-0.99.1/debian/changelog
--- upower-0.99.1/debian/changelog	2014-09-02 18:50:42.000000000 +0200
+++ upower-0.99.1/debian/changelog	2014-11-28 16:42:02.000000000 +0100
@@ -1,3 +1,12 @@
+upower (0.99.1-3.1) unstable; urgency=medium
+
+  * Non-maintainer upload.
+  * debian/patches/git-fix-memleak.patch
+    - Memleak fix.  Taken from upstream git head, commit 4221835f (Closes:
+      #766762). 
+
+ -- Michael Banck <mbanck at debian.org>  Fri, 28 Nov 2014 16:24:34 +0100
+
 upower (0.99.1-3) unstable; urgency=medium
 
   * debian/tests/build: Drop up_client_get_can_suspend() call, this got
diff -Nru upower-0.99.1/debian/patches/git-fix-memleak.patch upower-0.99.1/debian/patches/git-fix-memleak.patch
--- upower-0.99.1/debian/patches/git-fix-memleak.patch	1970-01-01 01:00:00.000000000 +0100
+++ upower-0.99.1/debian/patches/git-fix-memleak.patch	2014-11-28 16:23:18.000000000 +0100
@@ -0,0 +1,90 @@
+From 4221835fae97f875a23d0ce449e955f2ea488bbc Mon Sep 17 00:00:00 2001
+From: Peter Wu <peter at lekensteyn.nl>
+Date: Tue, 18 Nov 2014 06:04:08 +0100
+Subject: daemon: properly disconnect signals, stop memleak
+
+Whenever the daemon is polling on a device, a new signal is connected to
+the object. This signal was not disconnected when polling stops which
+resulted in a memory leak. Furthermore, whenever the "warning-level"
+property is updated, the signal would result in an exponentially raising
+call count (this happens when the battery percentage changes for
+example).
+
+https://bugs.freedesktop.org/show_bug.cgi?id=82659
+
+Reported-by: Alexander Jesner <alexander at jesner.eu>
+Signed-off-by: Peter Wu <peter at lekensteyn.nl>
+
+diff --git a/src/up-daemon.c b/src/up-daemon.c
+index 63ea7d1..d6420fc 100644
+--- a/src/up-daemon.c
++++ b/src/up-daemon.c
+@@ -69,6 +69,7 @@ struct UpDaemonPrivate
+ 	UpDeviceList		*power_devices;
+ 	guint			 action_timeout_id;
+ 	GHashTable		*poll_timeouts;
++	GHashTable		*idle_signals;
+ 
+ 	/* Properties */
+ 	gboolean		 on_battery;
+@@ -952,6 +953,7 @@ up_daemon_start_poll (GObject     *object,
+ 	UpDevice *device;
+ 	TimeoutData *data;
+ 	guint timeout;
++	ulong handler_id;
+ 	char *name;
+ 
+ 	device = UP_DEVICE (object);
+@@ -969,8 +971,10 @@ up_daemon_start_poll (GObject     *object,
+ 	timeout = calculate_timeout (device);
+ 	data->timeout = timeout;
+ 
+-	g_signal_connect (device, "notify::warning-level",
+-			  G_CALLBACK (change_idle_timeout), NULL);
++	handler_id = g_signal_connect (device, "notify::warning-level",
++				       G_CALLBACK (change_idle_timeout), NULL);
++	g_hash_table_insert (daemon->priv->idle_signals, device,
++			     GUINT_TO_POINTER (handler_id));
+ 	g_object_weak_ref (object, device_destroyed, daemon);
+ 
+ 	data->id = g_timeout_add_seconds (timeout, fire_timeout_callback, device);
+@@ -991,10 +995,20 @@ up_daemon_stop_poll (GObject *object)
+ 	UpDevice *device;
+ 	TimeoutData *data;
+ 	UpDaemon *daemon;
++	gpointer value;
++	gulong handle_id;
+ 
+ 	device = UP_DEVICE (object);
+ 	daemon = up_device_get_daemon (device);
+ 
++	value = g_hash_table_lookup (daemon->priv->idle_signals, device);
++	if (value != NULL) {
++		handle_id = GPOINTER_TO_UINT (value);
++		if (g_signal_handler_is_connected (device, handle_id))
++			g_signal_handler_disconnect (device, handle_id);
++		g_hash_table_remove (daemon->priv->idle_signals, device);
++	}
++
+ 	data = g_hash_table_lookup (daemon->priv->poll_timeouts, device);
+ 	if (data == NULL)
+ 		return;
+@@ -1137,6 +1151,7 @@ up_daemon_init (UpDaemon *daemon)
+ 
+ 	daemon->priv->poll_timeouts = g_hash_table_new_full (g_direct_hash, g_direct_equal,
+ 							     NULL, g_free);
++	daemon->priv->idle_signals = g_hash_table_new (g_direct_hash, g_direct_equal);
+ }
+ 
+ /**
+@@ -1281,6 +1296,7 @@ up_daemon_finalize (GObject *object)
+ 		g_source_remove (priv->props_idle_id);
+ 
+ 	g_clear_pointer (&priv->poll_timeouts, g_hash_table_destroy);
++	g_clear_pointer (&priv->idle_signals, g_hash_table_destroy);
+ 
+ 	g_clear_pointer (&daemon->priv->changed_props, g_hash_table_unref);
+ 	if (priv->proxy != NULL)
+-- 
+cgit v0.10.2
+
diff -Nru upower-0.99.1/debian/patches/series upower-0.99.1/debian/patches/series
--- upower-0.99.1/debian/patches/series	2014-09-02 18:50:42.000000000 +0200
+++ upower-0.99.1/debian/patches/series	2014-11-28 16:24:28.000000000 +0100
@@ -1,3 +1,4 @@
 git-tests-without-session-bus.patch
 git-tests-py3.4.patch
 git-split-tests.patch
+git-fix-memleak.patch


More information about the Pkg-utopia-maintainers mailing list