GNOME Bugzilla – Bug 681157
crash in GtkBuilder connect_signals()
Last modified: 2012-10-11 20:48:34 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:
+ Trace 230624
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?
Created attachment 220276 [details] Trivial C program
Created attachment 220278 [details] Equivalen python program
The test program works fine for me on linux/amd64, so it could be netbsd specific
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.
Created attachment 221860 [details] bt full
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?
BTW my libffi has the following patch applied: http://gcc.gnu.org/ml/java-patches/2010-q1/msg00058.html
It works on NetBSD-current/i386 - any clues on 64 vs 32 bit issues?
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?
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?
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.)
(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?
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):
+ Trace 230995
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.
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