GNOME Bugzilla – Bug 670863
PyGObject segfaults/aborts when reading/writing [respectively] a GObject pointer property that's been annotated to a GCallback
Last modified: 2018-01-10 20:14:21 UTC
###### SUMMARY: PyGObject segfaults/aborts when reading/writing [respectively] a GObject pointer property that's been annotated to a GCallback (or any other function/signature) ###### SIGSEGV on read [G_DEBUG=fatal-warnings] ------------------------------------------------------------------------------- (Pdb) [...] (Pdb) print self.listener.props.hicallback ** CRITICAL **: g_registered_type_info_get_g_type: assertion `GI_IS_REGISTERED_TYPE_INFO (info)' failed Program received signal SIGTRAP, Trace/breakpoint trap. 0x00007ffff57da0d3 in g_logv () from /usr/lib/libglib-2.0.so.0 (gdb) bt full
+ Trace 229746
[...] ------------------------------------------------------------------------------- ###### source header ------------------------------------------------------------------------------- typedef void (*WebKitDOMEventListenerCallback) (WebKitDOMEvent* event); [...] /** * WebKitDOMEventListener:hicallback: * * Type: WebKitDOMEventListenerCallback */ [...] ------------------------------------------------------------------------------- ###### source impl [WEBKIT_PARAM_READWRITE===G_PARAM_READWRITE w/cast for C++] ------------------------------------------------------------------------------- [...] g_object_class_install_property( gobjectClass, PROP_HICALLBACK, g_param_spec_pointer( "hicallback", "event_listener_hicallback", "read-write GCallback* WebKitDOMEventListener.hicallback", WEBKIT_PARAM_READWRITE ) ); [...] ------------------------------------------------------------------------------- ###### generated GIR excerpt ------------------------------------------------------------------------------- [...] <class name="DOMEventListener" c:symbol-prefix="dom_event_listener" c:type="WebKitDOMEventListener" parent="DOMObject" glib:type-name="WebKitDOMEventListener" glib:get-type="webkit_dom_event_listener_get_type" glib:type-struct="DOMEventListenerClass"> <method name="handle_event" c:identifier="webkit_dom_event_listener_handle_event"> <doc xml:whitespace="preserve">Returns:</doc> <return-value transfer-ownership="none"> <type name="none" c:type="void"/> </return-value> <parameters> <parameter name="evt" transfer-ownership="none"> <doc xml:whitespace="preserve">A #WebKitDOMEvent</doc> <type name="DOMEvent" c:type="WebKitDOMEvent*"/> </parameter> </parameters> </method> <property name="handler" writable="1" transfer-ownership="none"> <type name="GObject.Closure"/> </property> <property name="hicallback" writable="1" transfer-ownership="none"> <type name="DOMEventListenerCallback"/> </property> <field name="parent_instance"> <type name="DOMObject" c:type="WebKitDOMObject"/> </field> <field name="handler"> <type name="GObject.Closure" c:type="GClosure*"/> </field> </class> <callback name="DOMEventListenerCallback" c:type="WebKitDOMEventListenerCallback"> <return-value transfer-ownership="none"> <type name="none" c:type="void"/> </return-value> <parameters> <parameter name="event" transfer-ownership="none"> <type name="DOMEvent" c:type="WebKitDOMEvent*"/> </parameter> </parameters> </callback> [...] -------------------------------------------------------------------------------
(for some reason bugzilla ate/squashed the SIGABRT trace, this was suppose to follow the first ... will try to make a test case tomorrow) ###### SIGABRT on write ------------------------------------------------------------------------------- (Pdb) [...] (Pdb) self.listener.props.hicallback = lambda *x: x ** ERROR:pygi-argument.c:1022:_pygi_argument_from_object: code should not be reached Program received signal SIGABRT, Aborted. 0x00007ffff7496975 in raise () from /lib/libc.so.6 (gdb) bt full
+ Trace 229747
[...] -------------------------------------------------------------------------------
also, unless i'm missing something critical, it seems appropriate that a property based GCallback should *not require* a DestroyNotify callback, or any other special scope. once the property is replaced by a new pointer, or set to NULL, the FFI can be freed ... the caller [python] is in full control of this, and both python and any C-code should subscribe to property changes to be informed of the status (eg, C-code keeping a ref around and calling it after invalidation is a bug, but not in pygobject).
Created attachment 208481 [details] testcase SIGSEGV and SIGABORT simply chmod and run ... and maybe look it over too ;-) pulls 2 files from the gobject-introspection 1.3.0 tree and demonstrates the bug after ~5 seconds.
Confirmed with 3.2.0 using the attached test case. I just had to fix the linking order of the gcc call, for the record: gcc annotation.c $(pkg-config --cflags --libs gobject-2.0) -fPIC -shared -Wl,-soname,libannotation.so -o libannotation.so
Created attachment 212746 [details] testcase SIGSEGV and SIGABORT (revised) ahh .. yeah i'm still a bit n00b-esque in that regard. IIRC i just looked at the man page, which lists infile last; what gives? i seem to recall reading the output file should be first ... but meh, gcc does what it wants i guess! i'm not surprised in the least. uploaded a revised testcase. however, both versions work for me on latest GCC [archlinux/4.7.0])
-- GitLab Migration Automatic Message -- This bug has been migrated to GNOME's GitLab instance and has been closed from further activity. You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.gnome.org/GNOME/pygobject/issues/24.