GNOME Bugzilla – Bug 735166
Python wrongly releases floating variants consumed by a refsink
Last modified: 2014-10-18 02:45:21 UTC
Created attachment 284092 [details] test.py Python wrongly releases floating variants consumed by a g_variant_ref_sink. In the attached python code, the following warning will be printed: sys:1: Warning: g_variant_unref: assertion 'value->ref_count > 0' failed pygobject uses g_object_is_floating() to manage the reference counting of GObjects. But I don't find any references to g_variant_is_floating() in pygobject's source.
Confirmed, I'm somewhat surprised this hasn't surfaced until now. The g_object_is_floating() checks in use are generally hacks to work around bugs in underlying libraries or the oddity that g_object_new() is transfer-full but can return floating references. In the case of marshalling variants to Python, we always call g_variant_ref_sink() for transfer-none which handles the majority of cases (all the variant constructors) See: [1] The problem here is new_tuple() is actually statically implemented and does not go through this code path [2]. It also doesn't sink the resulting ref after the it calls g_variant_new_tuple() which is the bug here. The fix should be as simple as calling g_variant_ref_sink(). Since g_variant_new_tuple() sinks its inputs, the bug can also be seen as: t = GLib.Variant.new_tuple(GLib.Variant.new_tuple()) del t As an aside, while reading the code I also notice the temporary array passed to g_variant_new_tuple() is leaked. As another aside, we can probably delete this static binding as our array marshalling code path should handle all of this... but I'll save that for 3.16. [1] https://git.gnome.org/browse/pygobject/tree/gi/pygi-struct-marshal.c?id=3.13.90#n403 [2] https://git.gnome.org/browse/pygobject/tree/gi/gimodule.c?id=3.13.90#n472
(In reply to comment #1) > As an aside, while reading the code I also notice the temporary array passed to > g_variant_new_tuple() is leaked. Never mind, I didn't notice the "a" at the end of "g_newa".
A workaround is to use the Python constructor: tuple_v = GLib.Variant('(s)', ('org.freedesktop.DBus',)) The following fix has been pushed: c1d3875 Fix reference counting problems with GLib.Variant.new_tuple()
Created attachment 284147 [details] [review] Fix reference counting problems with GLib.Variant.new_tuple() Always sink the results of g_variant_new_tuple() in the statically bound wrapper. This matches the generic GI marshalling behavior of passing GVariants to Python with transfer-none.
*** Bug 738653 has been marked as a duplicate of this bug. ***