howl-editor / howl

The Howl Editor
http://howl.io
Other
712 stars 68 forks source link

Segfault on new view, with possible fix #3

Closed pinealservo closed 10 years ago

pinealservo commented 10 years ago

I'm really impressed with your work on this editor, and I'm definitely going to invest some time in learning to use it. I've already got a basic set of emacs keybindings ported, but as I was looking at the view-splitting commands, I ran into a segfault. I finally got a chance to dig into it, and it seems that there's an assertion that fails before it crashes:

Gtk-CRITICAL **: gtk_widget_event: assertion 'WIDGET_REALIZED_FOR_EVENT (widget, event)' failed

I then ran it like this: G_DEBUG="fatal_warnings" gdb ./howl I got a stack trace that looked interesting:

#0  0x00007ffff56be289 in g_logv () from /usr/lib/libglib-2.0.so.0
#1  0x00007ffff56be3d2 in g_log () from /usr/lib/libglib-2.0.so.0
#2  0x00007ffff749516a in gtk_widget_event () from /usr/lib/libgtk-3.so.0
#3  0x00007ffff74b222b in gtk_window_propagate_key_event ()
   from /usr/lib/libgtk-3.so.0
#4  0x00007ffff74b2261 in ?? () from /usr/lib/libgtk-3.so.0
#5  0x00007ffff736c5ee in ?? () from /usr/lib/libgtk-3.so.0
#6  0x00007ffff5b838d7 in ?? () from /usr/lib/libgobject-2.0.so.0
#7  0x00007ffff5b9c3a2 in g_signal_emit_valist ()
   from /usr/lib/libgobject-2.0.so.0
#8  0x00007ffff5b9d002 in g_signal_emit () from /usr/lib/libgobject-2.0.so.0
#9  0x00007ffff7494e7c in ?? () from /usr/lib/libgtk-3.so.0
#10 0x00007ffff736aabf in ?? () from /usr/lib/libgtk-3.so.0
#11 0x00007ffff736c1ca in gtk_main_do_event () from /usr/lib/libgtk-3.so.0
#12 0x00007ffff6f67162 in ?? () from /usr/lib/libgdk-3.so.0
#13 0x00007ffff56b7296 in g_main_context_dispatch ()
   from /usr/lib/libglib-2.0.so.0
#14 0x00007ffff56b75e8 in ?? () from /usr/lib/libglib-2.0.so.0
#15 0x00007ffff56b768c in g_main_context_iteration ()
   from /usr/lib/libglib-2.0.so.0
#16 0x00007ffff60910ac in g_application_run () from /usr/lib/libgio-2.0.so.0
#17 0x0000000000445aa2 in lj_vm_ffi_call ()
#18 0x0000000000466a26 in lj_ccall_func ()
---Type <return> to continue, or q <return> to quit---
#19 0x00000000004417b6 in lj_cf_ffi_meta___call ()
#20 0x00000000004438fe in lj_BC_FUNCC ()
#21 0x00000000004337e0 in lua_pcall ()
#22 0x00000000004282a3 in lua_run (L=0x40000378, 
    app_root=0x6fbf80 "/home/levi/howl", argv=<optimized out>, argc=1)
    at main.c:31
#23 main (argc=1, argv=0x7fffffffe208) at main.c:84

I also determined that the crash was happening in lib/howl/ui/window.moon in the add_view method, specifically in the gobject/show_all! call.

After a bit of searching, it seemed it might be related to the editor widget getting keyboard focus before being displayed. Following the hunch, I made the following changes, which seemed to fix the problem:

diff --git a/lib/howl/application.moon b/lib/howl/application.moon
index d4545fd..ef985a7 100644
--- a/lib/howl/application.moon
+++ b/lib/howl/application.moon
@@ -77,7 +77,7 @@ class Application extends PropertyObject
     editor = Editor opts.buffer or @next_buffer
     (opts.window or @window)\add_view editor, opts.placement or 'right_of'
     append @_editors, editor
-    --editor\grab_focus!
+    editor\grab_focus!
     editor

   new_buffer: (buffer_mode) =>
diff --git a/lib/howl/commands/ui_commands.moon b/lib/howl/commands/ui_commands.moon
index 107dede..2e0d161 100644
--- a/lib/howl/commands/ui_commands.moon
+++ b/lib/howl/commands/ui_commands.moon
@@ -97,8 +97,7 @@ for cmd in *{
       if target
         target\grab_focus!
       else
-        newEditor = howl.app\new_editor :placement
-        newEditor\grab_focus!
+        howl.app\new_editor :placement

   command.register
     name: "new-view-#{placement\gsub '_', '-'}",

I guess this must be due to a different version of gtk or something, because I can't imagine you wouldn't have run across it if it existed on your system. I'm running Arch on this machine, so things tend to be bleeding-edge.

nilnor commented 10 years ago

Thanks for the report, and thanks for taking the time dig into this!

As you guessed I haven't seen this myself, and I use multiple views on a regular basis. I'll see if I can get a virtual box of Arch up to verify this myself, what version are you using by the way?

The diff seems to be reversed, but from what I understand you've effectively moved the grab_focus call from the Application.new_editor method into the command. Seems like it should be same thing really, unless you have some other changes?

If you don't mind, could you list the minimal set of actions you take to reproduce this. From a newly started instance, do you see the segfault directly when you invoke, say, the view-right-or-create?

nilnor commented 10 years ago

I've managed to reproduce it now, will investigate further.

nilnor commented 10 years ago

Fixed in master. Turns out it was a reproducible problem in my own environment as well, once I turned off the VI mode. Verified to work for Ubuntu and Arch (14.03). Again, thanks for the report!

pinealservo commented 10 years ago

Whoops, yeah, the diff was reversed. I accidentally committed the change to the wrong branch of my local repository, fixed it, and then took the diff from the wrong branch. Guess I hadn't had enough sleep. Glad you were able to figure it out and get it fixed!

My thinking with the change I made was that if I ensured the new editor and view were built before I gave it focus, it would not trigger the assertion failure that I was seeing that was related to keyboard focus. It did seem to work, but I guess it was not the root cause.

Do you have any hints on tracking down this sort of error in luajit ffi programs? I have done some experiments with luajit myself, but it's easy to get the ffi setup wrong and get some very difficult to debug crashes.

nilnor commented 10 years ago

Well, it was weird that you saw an effect of moving the grab_focus call out, I can't make heads or tails out of that, that's why I wondered whether you had any additional changes. But I did not get the same backtraces either, so knows, it might just be that it was corruption deep down that manifested in different ways on different machines. I verified that the changes you made had no effect for me fwiw.

I don't have any good hints to offer unfortunately with regards to the FFI - I find it hard and cruel at times, and I've had my share of hard to diagnose crashes. That being said, this particular error would not have been easier to debug with better support, as the actual segfault occurred separately from the problematic call. Git bisect ended up being the saviour in this case.