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 681157 - crash in GtkBuilder connect_signals()
crash in GtkBuilder connect_signals()
Status: RESOLVED FIXED
Product: pygobject
Classification: Bindings
Component: gobject
3.2.x
Other NetBSD
: Normal critical
: ---
Assigned To: Nobody's working on this now (help wanted and appreciated)
Python bindings maintainers
Depends on:
Blocks:
 
 
Reported: 2012-08-03 18:17 UTC by Patrick Welche
Modified: 2012-10-11 20:48 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
GtkBuilder XML description (410 bytes, application/x-designer)
2012-08-03 18:17 UTC, Patrick Welche
Details
Trivial C program (469 bytes, text/x-csrc)
2012-08-03 18:18 UTC, Patrick Welche
Details
Equivalen python program (246 bytes, text/x-python)
2012-08-03 18:18 UTC, Patrick Welche
Details
bt full (11.14 KB, text/plain)
2012-08-20 17:29 UTC, Patrick Welche
Details

Description Patrick Welche 2012-08-03 18:17:45 UTC
Created attachment 220275 [details]
GtkBuilder XML description

Attached are a simple XML GtkBuilder file build.ui which has a single button in a window, a trivial C program build.c which works, and what is hopefully the same trivial program translated into python build.py.

When I run the C program, and click on the button, "hello" is printed at the console.

When I run the python program, I get a core dump:

  • #0 ??
  • #1 gtk_builder_connect_signals_full
    at gtkbuilder.c line 1490
  • #2 ffi_call_unix64
    at src/x86/unix64.S line 75
  • #3 ffi_call
    at src/x86/ffi64.c line 484
  • #4 g_callable_info_invoke
    at girepository/gicallableinfo.c line 610

etc.

If I comment out the line "gui.connect_signals(Handler())", the python program works, though isn't very useful. Likewise if I comment out the <signal.../> line in build.ui.

This is a NetBSD-current/amd64 system with gtk 3.4.4, pygobject 3.2.2.

This started out as Bug 673569: I couldn't work out why accerciser always coredumped - build.py should be a bit easier to debug than accerciser... Still, any idea where to look?
Comment 1 Patrick Welche 2012-08-03 18:18:15 UTC
Created attachment 220276 [details]
Trivial C program
Comment 2 Patrick Welche 2012-08-03 18:18:43 UTC
Created attachment 220278 [details]
Equivalen python program
Comment 3 Paolo Borelli 2012-08-06 07:05:20 UTC
The test program works fine for me on linux/amd64, so it could be netbsd specific
Comment 4 Martin Pitt 2012-08-20 11:08:30 UTC
Works for me as well (linux/amd64), with both python 2 and 3 (after fixing the print statement). Unfortunately the stack trace is rather useless, any chance to get a "bt full" with all debug symbols installed?

Can you also try to change the program like this:

-gui.connect_signals(Handler())
+handler = Handler()
+gui.connect_signals(handler)

Does that work? If so, it smells like a lost reference, as the Handler() object gets removed prematurely.
Comment 5 Patrick Welche 2012-08-20 17:29:35 UTC
Created attachment 221860 [details]
bt full
Comment 6 Patrick Welche 2012-08-20 17:31:17 UTC
Unfortunately connect_signals(handler) doesn't work either.

Not sure what to do about the stack trace: I had all the debug symbols installed.

In the meantime I tried again with python 2.7.3 rather than 2.6.8 so here is a new stack trace with that one.

Is there anything I can look for of use in the core file?
Comment 7 Patrick Welche 2012-08-20 17:34:10 UTC
BTW my libffi has the following patch applied:

http://gcc.gnu.org/ml/java-patches/2010-q1/msg00058.html
Comment 8 Patrick Welche 2012-08-26 21:23:17 UTC
It works on NetBSD-current/i386 - any clues on 64 vs 32 bit issues?
Comment 9 Martin Pitt 2012-08-27 04:10:47 UTC
Unfortunately the detailled stack trace doesn't tell us much more, the topmost function is connect_signals() and there is no enlightening stuff below.

> It works on NetBSD-current/i386 - any clues on 64 vs 32 bit issues?
> BTW my libffi has the following patch applied:
> http://gcc.gnu.org/ml/java-patches/2010-q1/msg00058.html

This patch is 64 bit specific. Perhaps try without the patch and see whether that helps?
Comment 10 Patrick Welche 2012-08-31 15:17:48 UTC
Unfortunately still no change...

Returning to the hopefully more easily debuggable original problem: how come attaching a signal works in C but not in python? Is python not effectively calling the same C function? If not, where in the code does this happen?
Comment 11 Patrick Welche 2012-09-14 13:08:14 UTC
I added some debugging print statements here and there.

When running the C program, gtk_builder_connect_signals(), gtk_builder_connect_signals_full() and gtk_builder_connect_signals_default() are called.

The python program calls site-packages/gi/overrides/Gtk.py connect_signals.
This calls self.connect_signals_full(_full_callback, obj_or_map) which effectively runs gtk_builder_connect_signals_full(). However, the function is not gtk_builder_connect_signals_default:

(gdb) print *func
$3 = {void (GtkBuilder *, GObject *, const gchar *, const gchar *, GObject *, 
    GConnectFlags, gpointer)} 0x7f7ff55af7c0

as opposed to

(gdb) print *func
$5 = {void (GtkBuilder *, GObject *, const gchar *, const gchar *, GObject *, 
    GConnectFlags, 
    gpointer)} 0x7f7ff74e6b50 <gtk_builder_connect_signals_default>


The crash happens when func() is called. BTW python override class Builder connect_signals _full_callback() is not called. (At least a print statement at the beginning doesn't appear.)
Comment 12 Patrick Welche 2012-09-18 09:34:28 UTC
(Pdb) bt
  /usr/pkg/lib/python2.7/bdb.py(387)run()
-> exec cmd in globals, locals
  <string>(1)<module>()
  /home/prlw1/NetBSD/atspi/ui/build.py(11)<module>()
-> gui.connect_signals(handler)
  /usr/pkg/lib/python2.7/site-packages/gi/overrides/Gtk.py(367)connect_signals()
-> self.connect_signals_full(_full_callback, obj_or_map)
  /usr/pkg/lib/python2.7/site-packages/gi/types.py(43)function()
-> return info.invoke(*args, **kwargs)
> /usr/pkg/lib/python2.7/site-packages/gi/module.py(231)__getattr__()
-> if name in override_exports:
(Pdb) getattr(self._overrides_module, 'Builder', None)
<class 'gi.overrides.Gtk.Builder'>

But then what is meant to happen? How does the gtk C function get called?
Comment 13 Simon Feltman 2012-10-08 11:45:24 UTC
Patrick,

I also do not see a crash (ubuntu 12.04 64bit). I doubt any of this will do much but here are a few random things to try in no particular order:

- Derive Handler from object: class Handler(object):

- Pass in a dictionary with a global callback: {'ok_func': ok_func}

- Verify the "hex(id(handler))" or whatever you pass in to connect_signals is the same value as "user_data" in #1 of the stack trace (I think it should be):
  • #1 gtk_builder_connect_signals_full
    at gtkbuilder.c line 1490

This may at least give you a hint pointers are correctly getting passed through gi/ffi to gtk.

- Call connect_signals_full directly passing it your own custom hookup func:
def full_callback(*args):
    print(args)
gui.connect_signals_full(full_callback, None)

- Find another Gtk or introspection based method which also takes a callback and see if it also crashes.


The segfault is occurring when gtk_connect_signals_full calls the func callback which is created by gi/ffi and passed in. I read through some of the code in gi/ffi but there isn't much I can tell without being able to debug this locally.
Comment 14 Patrick Welche 2012-10-11 20:48:34 UTC
Thank you for the suggestions. I got as far as showing that hex(id(handler)) was not equal to user_data, so pointers were not getting passed through gi/ffi to gtk.
The good news is that just now Matthias Drochner fixed this problem with libffi on NetBSD/amd64:

  http://mail-index.netbsd.org/pkgsrc-changes/2012/10/11/msg079577.html