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 779918 - gjs crashed with SIGSEGV in gjs_object_from_g_object
gjs crashed with SIGSEGV in gjs_object_from_g_object
Status: RESOLVED FIXED
Product: gjs
Classification: Bindings
Component: general
1.47.x
Other Linux
: Normal minor
: ---
Assigned To: Philip Chimento
gjs-maint
Depends on:
Blocks:
 
 
Reported: 2017-03-11 20:59 UTC by Iain Lane
Modified: 2017-03-29 04:23 UTC
See Also:
GNOME target: ---
GNOME version: ---


Attachments
bt full (38.53 KB, text/plain)
2017-03-14 10:33 UTC, Iain Lane
  Details
object: Don't crash on error in gjs_object_from_g_object() (1.45 KB, patch)
2017-03-14 22:03 UTC, Philip Chimento
committed Details | Review

Description Iain Lane 2017-03-11 20:59:59 UTC
Meh, turns out I was wrong and silencing the warning in bug #779871 didn't fix the testcase. It just silenced the warning, and I didn't notice that it was crashing because it didn't print any output.

This only seems to happen in a chroot(?) - jhbuild make check in libsecret works fine... That's annoying, because the package builds and the CI tests happen in chroots :(

Maybe you can understand this trace. I'm running gjs 1.47.91 + the patch from the bug, and testing libsecret 0.18.5. The test file in question is https://git.gnome.org/browse/libsecret/tree/libsecret/test-js-store.js - AFAICS the crash happens in the anonymous callback in password_store ().

root@autopkgtest-lxd-theaqj:/tmp/autopkgtest.rLHBf1/build.5ui/libsecret-0.18.5# LD_LIBRARY_PATH=.libs/ GI_TYPELIB_PATH=$(pwd) dbus-run-session -- gdb --args gjs libsecret/test-js-store.js 
[…]
Reading symbols from gjs...Reading symbols from /usr/lib/debug/.build-id/d2/14e5c0c36baf0d24d26c3711e44d97c77cb718.debug...done.
done.
(gdb) run
Starting program: /usr/bin/gjs libsecret/test-js-store.js
[…]
Thread 1 "gjs" received signal SIGSEGV, Segmentation fault.
0x00007ffff47a6f30 in JS_GetClass(JSObject*) () from /usr/lib/x86_64-linux-gnu/libjs.so.0
(gdb) bt
  • #0 JS_GetClass(JSObject*)
  • #1 gjs_object_from_g_object(JSContext*, GObject*)
    at gi/object.cpp line 2198
  • #2 gjs_value_from_g_argument(JSContext*, JS::MutableHandleValue, GITypeInfo*, GArgument*, bool)
    at gi/arg.cpp line 2844
  • #3 gjs_callback_closure(ffi_cif*, void*, void**, void*)
    at gi/function.cpp line 263
  • #4 ffi_closure_unix64_inner
  • #5 ffi_closure_unix64
  • #6 g_simple_async_result_complete
    at ../../../../gio/gsimpleasyncresult.c line 801
  • #7 on_store_create
    at libsecret/secret-methods.c line 1071
  • #8 g_simple_async_result_complete
    at ../../../../gio/gsimpleasyncresult.c line 801
  • #9 on_create_item_called
    at libsecret/secret-paths.c line 1988
  • #10 g_task_return_now
    at ../../../../gio/gtask.c line 1145
  • #11 g_task_return
    at ../../../../gio/gtask.c line 1203
  • #12 g_dbus_connection_call_done
    at ../../../../gio/gdbusconnection.c line 5710
  • #13 g_task_return_now
    at ../../../../gio/gtask.c line 1145
  • #14 complete_in_idle_cb
    at ../../../../gio/gtask.c line 1159
  • #15 g_main_dispatch
    at ../../../../glib/gmain.c line 3203
  • #16 g_main_context_dispatch
    at ../../../../glib/gmain.c line 3856
  • #17 g_main_context_iterate
    at ../../../../glib/gmain.c line 3929
  • #18 g_main_loop_run
    at ../../../../glib/gmain.c line 4125
  • #19 ffi_call_unix64
  • #20 ffi_call
  • #21 gjs_invoke_c_function(JSContext*, Function*, JS::HandleObject, JS::HandleValueArray const&, mozilla::Maybe<JS::MutableHandle<JS::Value> >&, GIArgument*)
    at gi/function.cpp line 1005
  • #22 function_call(JSContext*, unsigned int, JS::Value*)
    at gi/function.cpp line 1325
  • #23 0x00007ffff4506d48 in
  • #24 0x00007ffff44fc887 in
  • #25 0x00007ffff45069db in
  • #26 0x00007ffff4514f11 in
  • #27 0x00007ffff4515283 in
  • #28 0x00007ffff47ce6b8 in
  • #29 JS::Evaluate(JSContext*, JS::Handle<JSObject*>, JS::ReadOnlyCompileOptions const&, char const*, unsigned long, JS::MutableHandle<JS::Value>)
  • #30 gjs_eval_with_scope(JSContext*, JS::HandleObject, char const*, ssize_t, char const*, JS::MutableHandleValue)
    at gjs/jsapi-util.cpp line 938
  • #31 gjs_context_eval(GjsContext*, char const*, gssize, char const*, int*, GError**)
    at gjs/context.cpp line 755
  • #32 main(int, char**)
    at gjs/console.cpp line 281

Comment 1 Philip Chimento 2017-03-13 21:38:42 UTC
I can't reproduce this on my setup either. If you can garner a bit more information from the backtrace, that would be helpful:

- In frame 3, what are the values of i, n_jsargs and n_args?
- In frame 1, what are the values of proto and gtype? (use g_type_name() to get a human readable value for gtype)
- In frame 1, if proto is NULL which I expect it is, how did it get that way? Could you step through the call to gjs_lookup_object_prototype() from a few lines before the crash and see why it returned NULL? (Using rr instead of gdb may be helpful for this)
Comment 2 Iain Lane 2017-03-14 10:33:29 UTC
Created attachment 347905 [details]
bt full

Sure, I will do.

I assumed (:P) that you're on Fedora, so I tried to reproduce the failure there... here we go. This is using f25 via lxd from my Ubuntu system, but should be the same in a chroot or cloud instance or any other minimal thing.

  # dnf install git make automake gcc gcc-c++ mozjs38-devel redhat-rpm-config python3-dbus python3-gobject
  # dnf builddep gjs libsecret
  # git clone git://git.gnome.org/gjs.git
  # cd gjs; ./autogen.sh CFLAGS="-g -O0" CXXFLAGS="-g -O0"; make
  # cd ..; git clone git://git.gnome.org/libsecret.git; cd libsecret; ./autogen.sh; make
  # LD_LIBRARY_PATH=.libs/ GI_TYPELIB_PATH=$(pwd) dbus-run-session -- ../gjs/gjs-console libsecret/test-js-store.js

It doesn't print anything (so it looks like it succeeds!), but if you

  # echo $?
  139

it crashed!

So let's run under gdb (still on Fedora) and get what you asked for

  # LD_LIBRARY_PATH=.libs/ GI_TYPELIB_PATH=$(pwd) dbus-run-session -- ../gjs/libtool --mode=execute gdb --args ../gjs/gjs-console libsecret/test-js-store.j
  (gdb) frame 1
  #1  0x00007ffff7b1077f in gjs_object_from_g_object (context=0x655050, gobj=0x62c900 [GSimpleAsyncResult]) at gi/object.cpp:2197
  2197	                                       global));
  (gdb) print proto
  $1 = {<js::RootedBase<JSObject*>> = {<No data fields>}, stack = 0x655068, prev = 0x7fffffffc520, ptr = 0x0}
  (gdb) print g_type_name (gtype)
  [Thread 0x7fffe99aa700 (LWP 2881) exited]
  $2 = (const gchar *) 0x7ffff58f3440 "GSimpleAsyncResult"
  (gdb) frame 3
  #3  0x00007ffff7affa14 in gjs_callback_closure (cif=0x7663c8, result=0x7fffffffc960, args=0x7fffffffc7c0, data=0x766380) at gi/function.cpp:264
  264	                if (!gjs_value_from_g_argument(context, jsargs[n_jsargs++],
  (gdb) print i
  $3 = 1
  (gdb) print n_args
  $4 = 3
  (gdb) print n_jsargs
  $5 = 2
  (gdb)

and I'll attach a `bt full' too. I'm not too sure what to do with proto in frame 1. proto.ptr is NULL; is that what you mean? Looking at gjs_lookup_object_prototype, it returns the following

  (gdb) print *gjs_lookup_object_prototype (context, gtype)
  $1 = {<js::gc::Cell> = {<No data fields>}, shape_ = {<js::BarrieredBase<js::Shape*>> = {<js::BarrieredBaseMixins<js::Shape*>> = {<No data fields>}, value = 0x7fffea66cc40}, <No data fields>}, 
  group_ = {<js::BarrieredBase<js::ObjectGroup*>> = {<js::BarrieredBaseMixins<js::ObjectGroup*>> = {<No data fields>}, value = 0x7fffea69a640}, <No data fields>}, static MaxTagBits = 3, 
  static ITER_CLASS_NFIXED_SLOTS = 1, static MAX_BYTE_SIZE = 160}

Hope this is helpful & you can reproduce with my instructions. Let me know if you want anything more.
Comment 3 Philip Chimento 2017-03-14 21:58:44 UTC
Thanks. I'm actually on Endless OS but I was able to reproduce it nonetheless, using uninstalled GJS and libsecret as in your above instructions.

So, one problem is the known one of our importer code swallowing exceptions all over the place. I fixed this particular instance and I'll attach a patch for it in a moment. However, that doesn't fix the problem, just allowed me to figure out what was actually going on.

The crash is due to not being able to find GJS's internal GjsPrivate typelib. If I replace "GI_TYPELIB_PATH=$(pwd)" with "GI_TYPELIB_PATH=.:../gjs" in the invocation, it doesn't crash for me. Does that work for you as well?
Comment 4 Philip Chimento 2017-03-14 22:03:41 UTC
Created attachment 347960 [details] [review]
object: Don't crash on error in gjs_object_from_g_object()

Fix one spot where we ignore a JS exception from
gjs_lookup_object_prototype() which causes a crash later. Also fix
another spot where we would crash if JS_NewObjectWithGivenProto() fails,
though that is unlikely except on OOM.
Comment 5 Cosimo Cecchi 2017-03-15 01:12:29 UTC
Review of attachment 347960 [details] [review]:

Makes sense to me.
Comment 6 Iain Lane 2017-03-15 10:10:17 UTC
Aha! That's interesting - turns out my reproducer tickles the same problem in a different way. If I run against an *installed* gjs in a minimal environment, with this patch---

root@autopkgtest-lxd-rnjyjd:/tmp/autopkgtest.J8N01W/build.7RE/libsecret-0.18.5# LD_LIBRARY_PATH=.libs/ GI_TYPELIB_PATH=/usr/lib/gjs/girepository-1.0/:$(pwd) dbus-run-session -- gjs-console libsecret
/test-js-store.js

(gjs-console:26604): Gjs-WARNING **: JS ERROR: Error: Requiring GjsPrivate, version none: Typelib file for namespace 'Gtk', version '3.0' not found

Now it's possible to see that the problem is a missing dependency. :-)

Cheers!
Comment 7 Philip Chimento 2017-03-15 18:31:17 UTC
OK, thanks. I'll reduce the priority of this accordingly.
Comment 8 Philip Chimento 2017-03-29 04:23:07 UTC
Attachment 347960 [details] pushed as 5a45fff - object: Don't crash on error in gjs_object_from_g_object()