After an evaluation, GNOME has moved from Bugzilla to GitLab. Learn more about GitLab.
No new issues can be reported in GNOME Bugzilla anymore.
To report an issue in a GNOME project, go to GNOME GitLab.
Do not go to GNOME Gitlab for: Bluefish, Doxygen, GnuCash, GStreamer, java-gnome, LDTP, NetworkManager, Tomboy.
Bug 687522 - Objects returned from vfuncs should maintain floating reference
Objects returned from vfuncs should maintain floating reference
Status: RESOLVED FIXED
Product: pygobject
Classification: Bindings
Component: general
3.4.x
Other Linux
: Normal normal
: ---
Assigned To: Nobody's working on this now (help wanted and appreciated)
Python bindings maintainers
Depends on:
Blocks: 693111
 
 
Reported: 2012-11-03 16:51 UTC by Osmo Salomaa
Modified: 2013-02-08 11:00 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
gimarshallingtests: Add tests helpers for marshaling of object arguments (12.30 KB, patch)
2013-01-16 11:06 UTC, Simon Feltman
needs-work Details | Review
Add tests for vfunc object arguments and returns (14.03 KB, patch)
2013-01-16 11:07 UTC, Simon Feltman
needs-work Details | Review
gimarshallingtests: Add tests helpers for marshaling of object arguments (12.52 KB, patch)
2013-01-30 12:42 UTC, Simon Feltman
committed Details | Review
Add tests for vfunc object arguments and returns (23.06 KB, patch)
2013-01-30 12:44 UTC, Simon Feltman
committed Details | Review
Add better reference management for transient floating objects (15.61 KB, patch)
2013-02-02 05:58 UTC, Simon Feltman
needs-work Details | Review
Unify and refactor caller and callee GObject argument marshalers (16.03 KB, patch)
2013-02-06 04:20 UTC, Simon Feltman
needs-work Details | Review
Fix reference leaks with transient floating objects (24.48 KB, patch)
2013-02-08 09:05 UTC, Simon Feltman
reviewed Details | Review
Fix reference leaks with transient floating objects (24.63 KB, patch)
2013-02-08 10:36 UTC, Simon Feltman
none Details | Review
Fix reference leaks with transient floating objects (24.63 KB, patch)
2013-02-08 10:44 UTC, Simon Feltman
committed Details | Review

Description Osmo Salomaa 2012-11-03 16:51:09 UTC
Trying to run pygobject's appwindow.py demo gives the following error.

[liveuser@localhost demos]$ python appwindow.py
/usr/lib64/python2.7/site-packages/gi/types.py:47: Warning: g_object_set: assertion `G_IS_OBJECT (object)' failed
  return info.invoke(*args, **kwargs)

(appwindow.py:4056): Gtk-CRITICAL **: gtk_activatable_set_related_action: assertion `GTK_IS_ACTIVATABLE (activatable)' failed
/usr/lib64/python2.7/site-packages/gi/types.py:47: Warning: g_object_ref_sink: assertion `G_IS_OBJECT (object)' failed
  return info.invoke(*args, **kwargs)

(appwindow.py:4056): Gtk-CRITICAL **: gtk_widget_set_name: assertion `GTK_IS_WIDGET (widget)' failed

(appwindow.py:4056): Gtk-CRITICAL **: gtk_toolbar_insert: assertion `GTK_IS_TOOL_ITEM (item)' failed
/usr/lib64/python2.7/site-packages/gi/types.py:47: Warning: instance of invalid non-instantiatable type `<invalid>'
  return info.invoke(*args, **kwargs)
/usr/lib64/python2.7/site-packages/gi/types.py:47: Warning: g_signal_connect_data: assertion `G_TYPE_CHECK_INSTANCE (instance)' failed
  return info.invoke(*args, **kwargs)

(appwindow.py:4056): Gtk-CRITICAL **: gtk_menu_tool_button_set_menu: assertion `GTK_IS_MENU_TOOL_BUTTON (button)' failed
appwindow.py:407: Warning: g_object_unref: assertion `G_IS_OBJECT (object)' failed
  main()

The code that I assume fails is below.

class ToolMenuAction(Gtk.Action):
    __gtype_name__ = "GtkToolMenuAction"

    def do_create_tool_item(self):
        return Gtk.MenuToolButton()

I have used the same 'do_create_tool_item' approach in gaupol, where I have gotten a bug report [1] according to which this happens at least on fedora 18 and arch linux, both of which have the latest pygobject and gtk+. With earlier 3.x versions of pygobject and/or gtk+ this 'do_create_tool_item' approach used to work.

[1] https://bugzilla.gnome.org/show_bug.cgi?id=686608
Comment 1 Martin Pitt 2012-12-18 22:18:36 UTC
Confirmed.

Testing with python 3.3: 
- trunk and 3.4.2 fail with above bug
- 3.2.0, 3.2.2, and 3.0.4 just crash without any output

Testing with python 2.7:
- trunk and 3.4.2 fail with above bug
- 3.0.4 and 3.2.2 work

Bisecting leads to this commit which introduced this bug:

http://git.gnome.org/browse/pygobject/commit/?id=6ba6b7ba90122954bb421c23606e9516697ba147

Simon, any idea why the extra DECREF is bad here? Might Gtk.MenuToolButton() be a floating reference of some kind? (although this affects python refs, not GObject refs)
Comment 2 Martin Pitt 2012-12-18 22:25:13 UTC
FTR, when I comment out the decref on trunk, appwindow.py works again with python2.7. It still doesn't work with python 3.3.
Comment 3 Simon Feltman 2012-12-19 05:54:07 UTC
Taking a look...
Comment 4 Simon Feltman 2012-12-19 10:55:20 UTC
What's happening is the within the vfunc the new MenuToolButton is being created and then sunk by the python object wrapper. The marshaling code attempts to steal the gobject reference in this case. The python DECREF will then also destroy the gobject in this case because it essentially owns it.
I think when returning gobjects, we might always want to incref them regardless of if they are transfer full or none.

Depending on the urgency we could remove the Py_DECREF and let it leak again until this can be fixed properly. For confidence hacking at these tricky parts of the code, having ref count tests for different combinations (ones we don't already test) of the following concepts as applied to gobjects will be needed:

transfer none (bug 687522)
transfer full
floating ref (bug 661359)
owned ref
vfunc return (bug 687522)
vfunc out arg
vfunc in arg (bug 661359)
property get (bug 675726)
property set
Comment 5 Simon Feltman 2013-01-16 11:06:02 UTC
Created attachment 233582 [details] [review]
gimarshallingtests: Add tests helpers for marshaling of object arguments

Add a number of vfuncs and methods which can be used for testing
marshaling of objects with different combinations of ownership
transference. An important part of these test vfuncs and methods is
they do not pass object returns and arguments through them. Instead
the methods return reference counts and floating attributes. This allows
isolation and ensures any problem with round trip object marshaling
does not obscure what should be tested from the perspective of C as the
caller of a vfunc. Tests and vfuncs can then be written in any gi based
language.
Comment 6 Simon Feltman 2013-01-16 11:07:24 UTC
Created attachment 233583 [details] [review]
Add tests for vfunc object arguments and returns

Add tests which use different combinations of floating, transfer full,
transfer none, and held wrapper as in, out, or return arguments to vfuncs.
Most of these are marked as skip or expectedFailure due to various bugs
noted on the tests.
Comment 7 Martin Pitt 2013-01-17 06:51:59 UTC
Thanks Simon!

It would be nice if the new vfuncs in gimarshallingtests.c could get some comments what they do; in particular, it's not quite obvious why they are called "return_object_*" without returning anything, or why there are _none_ and _full_ alternatives which have exactly the same function and annotation signature (there is no (transfer) annotation anywhere).

Please feel free to push the tests, unless they cause aborts on the test suite; but it seems you already took care of that by skipping them.
Comment 8 Simon Feltman 2013-01-17 08:54:46 UTC
(In reply to comment #7)
> Thanks Simon!
> 
> It would be nice if the new vfuncs in gimarshallingtests.c could get some
> comments what they do; in particular, it's not quite obvious why they are
> called "return_object_*" without returning anything, or why there are _none_
> and _full_ alternatives which have exactly the same function and annotation
> signature (there is no (transfer) annotation anywhere).

Will do. The methods are simply helpers for calling vfuncs which have those annotations. So perhaps I should name them as "call_vfunc_..."
For now, I'll mark these patches as needing work and wait a little more bit before committing.
Comment 9 Simon Feltman 2013-01-30 12:42:04 UTC
Created attachment 234823 [details] [review]
gimarshallingtests: Add tests helpers for marshaling of object arguments

Added comments and simplified the number of test helper methods by allowing a GType are to be passed for the type of object creation.
Comment 10 Simon Feltman 2013-01-30 12:44:48 UTC
Created attachment 234824 [details] [review]
Add tests for vfunc object arguments and returns

Breaks tests out into a new file (test_object_marshaling.py) because test_gi is getting too big. Eventually other object marshaling tests (besides vfunc tests) can move into this new file as well.
Comment 11 Martin Pitt 2013-01-30 13:33:28 UTC
Comment on attachment 234823 [details] [review]
gimarshallingtests: Add tests helpers for marshaling of object arguments

Thanks for the additional documentation! That helps.
Comment 12 Martin Pitt 2013-01-30 13:35:09 UTC
Comment on attachment 234824 [details] [review]
Add tests for vfunc object arguments and returns

Thanks, please go ahead with this.
Comment 13 Simon Feltman 2013-01-31 01:08:32 UTC
Comment on attachment 234823 [details] [review]
gimarshallingtests: Add tests helpers for marshaling of object arguments

Pushed with some additional cleanup
Comment 14 Simon Feltman 2013-01-31 01:27:37 UTC
Comment on attachment 234824 [details] [review]
Add tests for vfunc object arguments and returns

Pushed with some additional test method renaming and Python 2.7 fixes.

Attachment 234824 [details] pushed as 97f48f5 - Add tests for vfunc object arguments and returns
Comment 15 Simon Feltman 2013-02-02 05:58:43 UTC
Created attachment 235051 [details] [review]
Add better reference management for transient floating objects

Track PyObject wrappers which sink GObjects that are initially
floating. This allows for re-floating them when the GObject is
only temporary passed through the Python boundary and avoids
both leaks and invalid objects passed to C.
Print warning when a callback/vfunc is returning the last
reference to an object which will no longer be managed by Python.
Remove "private_flags" union on PyGObject as this class does
not have a public API anymore.
Comment 16 Simon Feltman 2013-02-06 04:20:12 UTC
Created attachment 235285 [details] [review]
Unify and refactor caller and callee GObject argument marshalers

Combine code from the large switch statement used to marshal
arguments to and from vfuncs/closures with the marshalers used
for direct calls to gi functions. This fixes a reference leak
when marshaling GObjects to Python with transfer=full due to
the diverging code paths.
Comment 17 Simon Feltman 2013-02-08 09:05:54 UTC
Created attachment 235491 [details] [review]
Fix reference leaks with transient floating objects

Unify and refactor caller and callee GObject argument marshalers.
Combine code from the large switch statement used to marshal
arguments to and from vfuncs/closures with the marshalers used
for direct calls to gi functions. This fixes a reference leak
when marshalling GObjects to Python with transfer=full due to
the diverging code paths.
Replace ability in gobject_new_full to optionally sink objects
with ability to optionaly "steal" objects. This fits the premis
that binding layers should always sink object initially. The
steal argument is then used for marshalling arguments which are
transfer=full.
Add hacks and comments to work around GTK+ bugs 693393 and 693400.
Comment 18 Martin Pitt 2013-02-08 10:17:30 UTC
Comment on attachment 235491 [details] [review]
Fix reference leaks with transient floating objects

Thanks Simon! I like this a lot, it makes the code quite bit simpler and clearer, and makes assumptions more explicit.

> with ability to optionaly "steal" objects. This fits the premis

"premise"

+static inline gboolean
+pygi_marshal_from_py_object (PyObject *pyobj,  /*in*/

+static inline PyObject *
+pygi_marshal_to_py_object (GIArgument *arg, GITransfer transfer) {

Should these really be inline? They are quite nontrivial, and even bound to change in the future (see the HACKS). When having them inline, stuff that builds against pygobject needs to get recompiled.
Comment 19 Simon Feltman 2013-02-08 10:36:14 UTC
Created attachment 235496 [details] [review]
Fix reference leaks with transient floating objects

Move inline functions into respective C files.
Comment 20 Simon Feltman 2013-02-08 10:44:06 UTC
Created attachment 235497 [details] [review]
Fix reference leaks with transient floating objects

Fixed spelling and moved inline functions into respective C files.
Comment 21 Martin Pitt 2013-02-08 10:57:05 UTC
Comment on attachment 235497 [details] [review]
Fix reference leaks with transient floating objects

Thanks!
Comment 22 Simon Feltman 2013-02-08 11:00:15 UTC
Attachment 235497 [details] pushed as 5efe2e5 - Fix reference leaks with transient floating objects