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 745225 - eventcontroller: Don't crash if the widget is destroyed first
eventcontroller: Don't crash if the widget is destroyed first
Status: RESOLVED FIXED
Product: gtk+
Classification: Platform
Component: Class: GtkGesture
3.14.x
Other All
: Normal normal
: ---
Assigned To: gtk-bugs
gtk-bugs
Depends on:
Blocks:
 
 
Reported: 2015-02-26 15:28 UTC by Vadim Rutkovsky
Modified: 2015-03-02 10:57 UTC
See Also:
GNOME target: 3.16
GNOME version: ---


Attachments
eventcontroller: Don't crash if the widget is destroyed first (1.01 KB, patch)
2015-03-01 12:36 UTC, Debarshi Ray
none Details | Review
eventcontroller, widget: Don't crash if destroyed before the other (2.21 KB, patch)
2015-03-01 18:36 UTC, Debarshi Ray
none Details | Review
eventcontroller, widget: Don't crash if destroyed before the other (2.21 KB, patch)
2015-03-01 18:44 UTC, Debarshi Ray
committed Details | Review
eventcontroller: Chain up on constructed (899 bytes, patch)
2015-03-01 18:46 UTC, Debarshi Ray
committed Details | Review

Description Vadim Rutkovsky 2015-02-26 15:28:28 UTC
Crashes on latest continuous 20150226.42.
gnome-documents 3.15.90-19-g6ebddf816f321b7e0121bde55de4ab4e58557e42:


           PID: 1976 (gjs-console)
           UID: 1000 (test)
           GID: 1000 (test)
        Signal: 11 (SEGV)
     Timestamp: Thu 2015-02-26 15:24:33 GMT (53s ago)
  Command Line: /usr/bin/gjs-console -I /usr/share/gnome-documents/js -c const Main = imports.main; Main.start(); --gapplication-service
    Executable: /usr/bin/gjs-console
 Control Group: /user.slice/user-1000.slice/session-6.scope
          Unit: session-6.scope
         Slice: user-1000.slice
       Session: 6
     Owner UID: 1000 (test)
       Boot ID: 6d9c3de245234b36b33251627810a1bc
    Machine ID: 45bb3b96146aa94f299b9eb43646eb35
      Hostname: qemux86-64
      Coredump: /var/lib/systemd/coredump/core.gjs-console.1000.6d9c3de245234b36b33251627810a1bc.1976.1424964273000000.xz
       Message: Process 1976 (gjs-console) of user 1000 dumped core.


Core was generated by `/usr/bin/gjs-console -I /usr/share/gnome-documents/js -c const Main = imports.m'.
Program terminated with signal SIGSEGV, Segmentation fault.
  • #0 _gtk_widget_remove_controller
    at ../../gtk/gtkwidget.c line 17242
  • #0 _gtk_widget_remove_controller
    at ../../gtk/gtkwidget.c line 17242
  • #1 gtk_event_controller_dispose
    at ../../gtk/gtkeventcontroller.c line 130
  • #2 g_object_unref
    at ../../gobject/gobject.c line 3133
  • #3 release_native_object
    at ../gi/object.cpp line 1107

Comment 1 Debarshi Ray 2015-03-01 12:32:52 UTC
This is what happens:

gesture = gtk_gesture_multi_press_new (widget);
gtk_widget_destroy (widget);
g_object_unref (gesture);

We could work it around in the application by swapping the order of the last two lines, but I think we should fix gtk+.
Comment 2 Debarshi Ray 2015-03-01 12:36:43 UTC
Created attachment 298203 [details] [review]
eventcontroller: Don't crash if the widget is destroyed first
Comment 3 Debarshi Ray 2015-03-01 14:17:34 UTC
Here is a better back trace:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff759ff4d in _gtk_widget_remove_controller (widget=0xca2320,
    controller=0xc7cf90) at gtkwidget.c:17242
17242     g_return_if_fail (GTK_IS_WIDGET (widget));
(gdb) bt

Thread 1 (Thread 0x7ffff7fb5a00 (LWP 30828))

  • #0 _gtk_widget_remove_controller
    at gtkwidget.c line 17242
  • #1 gtk_event_controller_dispose
    at gtkeventcontroller.c line 130
  • #2 g_object_unref
    at gobject.c line 3133
  • #3 release_native_object
    at gi/object.cpp line 1107
  • #4 object_instance_finalize
    at gi/object.cpp line 1433
  • #5 bool FinalizeTypedArenas<JSObject>(js::FreeOp*, js::gc::ArenaHeader**, js::gc::ArenaList&, js::gc::AllocKind, js::SliceBudget&) [clone .isra.216]
    from /lib64/libmozjs-24.so
  • #6 js::gc::ArenaLists::queueObjectsForSweep(js::FreeOp*)
    from /lib64/libmozjs-24.so
  • #7 BeginSweepingZoneGroup(JSRuntime*)
    from /lib64/libmozjs-24.so
  • #8 IncrementalCollectSlice(JSRuntime*, long, JS::gcreason::Reason, js::JSGCInvocationKind)
    from /lib64/libmozjs-24.so
  • #9 GCCycle(JSRuntime*, bool, long, js::JSGCInvocationKind, JS::gcreason::Reason)
    from /lib64/libmozjs-24.so
  • #10 Collect(JSRuntime*, bool, long, js::JSGCInvocationKind, JS::gcreason::Reason) [clone .part.234]
    from /lib64/libmozjs-24.so
  • #11 gjs_gc_if_needed
    at gjs/jsapi-util.cpp line 1199
  • #12 trigger_gc_if_needed
    at gjs/context.cpp line 539
  • #13 g_main_dispatch
    at gmain.c line 3122
  • #14 g_main_context_dispatch
    at gmain.c line 3737
  • #15 g_main_context_iterate
    at gmain.c line 3808
  • #16 g_main_context_iteration
    at gmain.c line 3869
  • #17 g_application_run
    at gapplication.c line 2308
  • #18 ffi_call_unix64
    from /lib64/libffi.so.6
  • #19 ffi_call
    from /lib64/libffi.so.6
  • #20 gjs_invoke_c_function
    at gi/function.cpp line 997
  • #21 function_call
    at gi/function.cpp line 1320
  • #22 js::Invoke(JSContext*, JS::CallArgs, js::MaybeConstruct)
    from /lib64/libmozjs-24.so
  • #23 Interpret(JSContext*, js::RunState&)
    from /lib64/libmozjs-24.so
  • #24 js::ExecuteKernel(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value const&, js::ExecuteType, js::AbstractFramePtr, JS::Value*)
    from /lib64/libmozjs-24.so
  • #25 js::Execute(JSContext*, JS::Handle<JSScript*>, JSObject&, JS::Value*)
    from /lib64/libmozjs-24.so
  • #26 JS::Evaluate(JSContext*, JS::Handle<JSObject*>, JS::CompileOptions, unsigned short const*, unsigned long, JS::Value*)
    from /lib64/libmozjs-24.so
  • #27 JS::Evaluate(JSContext*, JS::Handle<JSObject*>, JS::CompileOptions, char const*, unsigned long, JS::Value*)
    from /lib64/libmozjs-24.so
  • #28 gjs_eval_with_scope
  • #29 gjs_context_eval
  • #30 main
    at gjs/console.cpp line 140

Comment 4 Matthias Clasen 2015-03-01 15:25:43 UTC
This is now crashing because of

commit b8e87d47626afd7d6271425a5772f2ee774d1b78
Author: Carlos Garnacho <carlosg@gnome.org>
Date:   Wed Jan 14 16:59:36 2015 +0100

    widget: Free the controller list on finalize()
    
    If this is done on dispose(), the widget may be destroyed (and its
    controllers list NULLified) within _gtk_widget_run_controllers(),
    causing warnings/crashes when it just tried to hop on the next
    controllers.
    
    Freeing the controllers here should be a safety net for implementations,
    so it also makes sense to do this late. The widgets that choose to
    free their controllers on dispose can still do so, and get
    _gtk_widget_remove_controller() called for these as an indirect result.


This needs to be reconsidered.
Comment 5 Debarshi Ray 2015-03-01 15:45:38 UTC
Yes, just realized that:

Program received signal SIGSEGV, Segmentation fault.
0x00007ffff759f2d3 in _gtk_widget_remove_controller (
    widget=widget@entry=0xba2c50, controller=0x7de5f0) at gtkwidget.c:17247
17247	  g_return_if_fail (GTK_IS_EVENT_CONTROLLER (controller));
(gdb) bt
  • #0 _gtk_widget_remove_controller
    at gtkwidget.c line 17247
  • #1 gtk_widget_finalize
    at gtkwidget.c line 12185
  • #2 g_object_unref
    at gobject.c line 3170
  • #3 gtk_box_forall
    at gtkbox.c line 2574
  • #4 gtk_container_destroy
    at gtkcontainer.c line 1524
  • #5 g_closure_invoke
    at gclosure.c line 768
  • #6 signal_emit_unlocked_R
    at gsignal.c line 3665
  • #7 g_signal_emit_valist
    at gsignal.c line 3305
  • #8 g_signal_emit
    at gsignal.c line 3361
  • #9 gtk_widget_dispose
    at gtkwidget.c line 11949
  • #10 g_object_run_dispose
    at gobject.c line 1076
  • #11 gtk_box_forall
    at gtkbox.c line 2558
  • #12 gtk_container_destroy
    at gtkcontainer.c line 1524
  • #13 g_closure_invoke
    at gclosure.c line 768
  • #14 signal_emit_unlocked_R
    at gsignal.c line 3665
  • #15 g_signal_emit_valist
    at gsignal.c line 3305
  • #16 g_signal_emit
    at gsignal.c line 3361
  • #17 gtk_widget_dispose
    at gtkwidget.c line 11949
  • #18 g_object_run_dispose
    at gobject.c line 1076
  • #19 ffi_call_unix64
    at ../src/x86/unix64.S line 76
  • #20 ffi_call
    at ../src/x86/ffi64.c line 525
  • #21 gjs_invoke_c_function
    at gi/function.cpp line 972
  • #22 function_call
    at gi/function.cpp line 1294
  • #23 CallJSNative
    at /usr/src/debug/mozjs-24.2.0/js/src/jscntxtinlines.h line 321
  • #24 js::Invoke
  • #25 Interpret
    at /usr/src/debug/mozjs-24.2.0/js/src/vm/Interpreter.cpp line 2298
  • #26 js::RunScript
    at /usr/src/debug/mozjs-24.2.0/js/src/vm/Interpreter.cpp line 438
  • #27 js::Invoke
  • #28 js_fun_apply
    at /usr/src/debug/mozjs-24.2.0/js/src/jsfun.cpp line 982
  • #29 CallJSNative
    at /usr/src/debug/mozjs-24.2.0/js/src/jscntxtinlines.h line 321
  • #30 js::Invoke
  • #31 js::Invoke
    at /usr/src/debug/mozjs-24.2.0/js/src/vm/Interpreter.cpp line 531
  • #32 js::jit::DoCallFallback
    at /usr/src/debug/mozjs-24.2.0/js/src/jit/BaselineIC.cpp line 7007
  • #33 ??
  • #34 ??
  • #35 ??
  • #36 ??
  • #37 ??
  • #38 js::jit::CreateThisInfo
    from /lib64/libmozjs-24.so
  • #39 ??
  • #40 ??
  • #41 ??
  • #42 ??
  • #43 ??
  • #44 ??
  • #45 ??
  • #46 ??
  • #47 ??
  • #48 ??
  • #49 ??
  • #50 ??
  • #51 ??
  • #52 ??
  • #53 ??
  • #54 ??
  • #55 ??
  • #56 ??
  • #57 ??
  • #58 ??
  • #59 ??
  • #60 ??
  • #61 ??
  • #62 ??
  • #63 ??
  • #64 ??
  • #65 ??
  • #66 ??
  • #67 g_param_spec_pool_lookup
    at gparam.c line 1076
  • #68 ??
  • #69 ??
  • #70 ??

Comment 6 Debarshi Ray 2015-03-01 18:07:49 UTC
One solution could be to have GtkWidget hold a reference to each GtkEventController in the list. After all, widgets can own controllers, and not the other way round.
Comment 7 Debarshi Ray 2015-03-01 18:36:13 UTC
Created attachment 298222 [details] [review]
eventcontroller, widget: Don't crash if destroyed before the other

Or, how about a weak reference in both directions? We might need to add a few NULL checks in that case.
Comment 8 Debarshi Ray 2015-03-01 18:44:31 UTC
Created attachment 298223 [details] [review]
eventcontroller, widget: Don't crash if destroyed before the other

Fix a typo in the commit message.
Comment 9 Debarshi Ray 2015-03-01 18:46:27 UTC
Created attachment 298224 [details] [review]
eventcontroller: Chain up on constructed
Comment 10 Muhammet Kara 2015-03-01 19:16:28 UTC
The patches worked for me. Gnome-documents no longer crashes.
Comment 11 Carlos Garnacho 2015-03-02 10:47:51 UTC
Comment on attachment 298223 [details] [review]
eventcontroller, widget: Don't crash if destroyed before the other

Looks good to me, I guess the oddity comes from gtk_gesture*_new() "attaching" the gesture to the widget, but also returning ref_count=1 on the controller, I can see how that confuses bindings... Using weak refs in this scenario looks proper.
Comment 12 Carlos Garnacho 2015-03-02 10:48:04 UTC
Comment on attachment 298224 [details] [review]
eventcontroller: Chain up on constructed

Looks good, the GObject contructed vmethod is blank, but better to just upchain indeed.
Comment 13 Debarshi Ray 2015-03-02 10:57:13 UTC
Thanks, Carlos.