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 774673 - Windows-only crash on GI functions with callbacks
Windows-only crash on GI functions with callbacks
Status: RESOLVED OBSOLETE
Product: gjs
Classification: Bindings
Component: general
unspecified
Other Windows
: Normal major
: ---
Assigned To: gjs-maint
gjs-maint
Depends on:
Blocks:
 
 
Reported: 2016-11-18 12:40 UTC by siavolt
Modified: 2018-01-27 12:02 UTC
See Also:
GNOME target: ---
GNOME version: ---



Description siavolt 2016-11-18 12:40:36 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!
Comment 1 Philip Chimento 2016-11-19 06:32:24 UTC
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?
Comment 2 siavolt 2016-12-06 16:53:36 UTC
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/
Comment 3 Philip Chimento 2016-12-09 07:10:33 UTC
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.
Comment 4 Philip Chimento 2017-01-03 08:15:56 UTC
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
Comment 5 Philip Chimento 2017-01-04 06:09:50 UTC
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
  • #0 sys_alloc
    at /usr/src/debug/libffi-3.2.1-2/src/dlmalloc.c line 3551
  • #1 dlmalloc
    at /usr/src/debug/libffi-3.2.1-2/src/dlmalloc.c line 4245
  • #2 ffi_closure_alloc
    at /usr/src/debug/libffi-3.2.1-2/src/closures.c line 616
  • #3 g_callable_info_prepare_closure
    from /usr/bin/cyggirepository-1.0-1.dll
  • #4 gjs_callback_trampoline_new
    at gi/function.cpp line 502
  • #5 gjs_invoke_c_function
    at gi/function.cpp line 871
  • #6 function_call
    at gi/function.cpp line 1320
  • #5 gjs_invoke_c_function
    at gi/function.cpp line 871

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?
Comment 6 Fan, Chun-wei 2017-01-18 02:40:58 UTC
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!
Comment 7 GNOME Infrastructure Team 2018-01-27 12:02:44 UTC
-- 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.