GNOME Bugzilla – Bug 774673
Windows-only crash on GI functions with callbacks
Last modified: 2018-01-27 12:02:44 UTC
Hi, have problem with TreeView widget after use set_cell_data_func method. More details you can get here: https://gist.github.com/siavolt/844785e4cf6efdc828ce6a24cf8e9754 Thanks!
I will try to reproduce these crashes locally, but from your email I understand that they are Windows-only. Would you be able to try again with GJS 1.47.0 or master?
Hi, Philip We have tested our app with 1.47, but unfortunately it remained the same problem. You can reproduce this bug with Windows VM + Cygwin. If you have any question, please ask. https://developer.microsoft.com/en-us/microsoft-edge/tools/vms/
OK, I hope I'll have some time to set up a Windows VM soon. We're going to release another 1.47.x next week with SpiderMonkey 31 so if you get a chance to try that, the bug may be fixed. But I'd say it's unlikely so no rush.
OK, I have reproduced the problem on a Windows 10 VM, with GJS at commit 2377ea12, all dependencies installed from Cygwin, and these changes applied: diff --git a/Makefile-insttest.am b/Makefile-insttest.am index f4b94ac..6a48b23 100644 --- a/Makefile-insttest.am +++ b/Makefile-insttest.am @@ -48,7 +48,7 @@ jsunit-resources.c: $(srcdir)/installed-tests/js/jsunit.gresources.xml $(jsunit_ BUILT_SOURCES += jsunit-resources.h jsunit-resources.c CLEANFILES += jsunit-resources.h jsunit-resources.c -common_test_ldflags = -avoid-version +common_test_ldflags = -avoid-version -no-undefined common_test_libadd = $(GJS_LIBS) privlibdir = $(pkglibdir) diff --git a/gjs/jsapi-util-string.cpp b/gjs/jsapi-util-string.cpp index f845d15..1edc2a3 100644 --- a/gjs/jsapi-util-string.cpp +++ b/gjs/jsapi-util-string.cpp @@ -80,7 +80,7 @@ gjs_string_from_utf8(JSContext *context, */ error = NULL; - u16_string = g_utf8_to_utf16(utf8_string, + u16_string = (jschar *) g_utf8_to_utf16(utf8_string, n_bytes, NULL, &u16_string_length, Here's a minimal script to reproduce the segfault: const Gio = imports.gi.Gio; const Mainloop = imports.mainloop; let file = Gio.File.new_for_path('COPYING'); file.load_contents_async(null, (obj, res) => { let [, contents] = obj.load_contents_finsh(res); Mainloop.quit('load'); }); Mainloop.run('load'); I'm pretty sure this bizarre behaviour is the problem: Breakpoint 1, gjs_invoke_c_function (context=context@entry=0x6000a0a70, function=function@entry=0x600042760, obj=obj@entry=0x6ffffc71190, js_argc=js_argc@entry=0, js_argv=js_argv@entry=0x6001252e0, js_rval=js_rval@entry=0xffffbed0, r_value=r_value@entry=0x0) at gi/function.cpp:675 675 { (gdb) next # ...a few times... 727 c_argc = function->invoker.cif.nargs; (gdb) 728 gi_argc = g_callable_info_get_n_args( (GICallableInfo*) function->info); (gdb) print c_argc $1 = 0 '\000' (gdb) print function->invoker.cif.nargs $2 = 1
OK, on second thought the bizarre behaviour goes away if I debug-print c_argc, so it must be some optimization (even though I compiled without optimization!) Here's a better minimal script because 1) you don't need to run a main loop and 2) I can get a useful backtrace from it: const Gtk = imports.gi.Gtk; Gtk.init(null); let tree = new Gtk.TreeView(); let col = new Gtk.TreeViewColumn(); let text1 = new Gtk.CellRendererText(); col.set_cell_data_func(text1, () => {}); Here's the relevant portion of the backtrace: Program received signal SIGSEGV, Segmentation fault. 0x00000003fceb3248 in sys_alloc (m=0x3fcebb040 <_gm_>, nb=72) at /usr/src/debug/libffi-3.2.1-2/src/dlmalloc.c:3551 3551 (void)set_segment_flags(&m->seg, mmap_flag); (gdb) bt
+ Trace 237035
The context is NULL, even though it was set to a valid-looking pointer at the function's entry. And there's really nothing in gjs_invoke_c_function() that would overwrite the context. Both of these facts suggest to me that the stack is getting clobbered. Breakpoint 1, gjs_invoke_c_function (context=context@entry=0x6000a0ac0, function=function@entry=0x6004319e0, obj=obj@entry=0x6ffffc39140, js_argc=js_argc@entry=2, js_argv=js_argv@entry=0x600125288, js_rval=js_rval@entry=0xffffbed0, r_value=r_value@entry=0x0) at gi/function.cpp:675 675 { (gdb) watch context Watchpoint 2: context (gdb) next [New Thread 3636.0x2e4] 701 GError *local_error = NULL; (gdb) 715 if (completed_trampolines) { (gdb) Watchpoint 2: context Old value = (JSContext *) 0x6000a0ac0 New value = (JSContext *) 0x0 gjs_invoke_c_function (context=0x0, context@entry=0x6000a0ac0, function=function@entry=0x6004319e0, obj=obj@entry=0x6ffffc39140, js_argc=2148882713, js_argc@entry=2, js_argv=js_argv@entry=0x600125288, js_rval=js_rval@entry=0xffffbed0, r_value=r_value@entry=0x0) at gi/function.cpp:724 724 is_method = g_callable_info_is_method(function->info); (gdb) Indeed, context and js_argc have been overwritten here. But by what?
Hi, I do realize this is somewhat late since the gjs codebase moved to SpiderMonkey31, but might be something worth noting... In gjs_string_from_ucs4(), I just declared u16_string as a jschar* rather than On Windows, since jschar is defined differently than on *NIX (which is uint16_t on *NIX), I declared u16_string as a jschar* rather than a uint16_t* and casted the results of the following g_ucs4_to_utf16() call to jschar * and the code built and linked properly, since Visual Studio is more strict on type checking in terms of compilation, and without this change the code will fail to link on Visual Studio. The minimal scripts ran successfully for me on 1.47.0 with no crashes. Hope this helps. With blessings, and cheers!
-- 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/gjs/issues/101.