mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
TUI: Skip redundant "stop" event (macOS kernel panic) (#9007)
When the TUI suspends (:suspend, CTRL-z) it calls tui_terminal_stop (but does NOT set `ui->data=NULL`, so `tui_is_stopped` returns false). If the host terminal dies, it sends SIGCONT, SIGHUP (usually in that order): ERROR 2018-09-16T19:30:17.065 25821 suspend_event:1153: SIGCONT ERROR 2018-09-16T19:30:17.065 25821 on_signal:162: SIGHUP ERROR 2018-09-16T19:30:17.155 25821 on_signal:162: SIGHUP Race: if SIGHUP is handled before SIGCONT, it calls ui_builtin_stop() which schedules tui_stop before the TUI was resumed? libuv uv_close() aborts if the handle is already closed/closing. Somehow that causes macOS to panic. #8075 Assertion failed: (!uv__is_closing(handle)), function uv_close, file src/unix/core.c, line 117. Thread 0:: Dispatch queue: com.apple.main-thread 0 libsystem_kernel.dylib 0x00007fff67d69ec2 kevent + 10 1 libuv.1.dylib 0x000000010609304d uv__io_poll + 892 2 libuv.1.dylib 0x0000000106083904 uv_run + 339 3 nvim 0x0000000105e76f7b loop_poll_events + 74 4 nvim 0x0000000105fa5f51 ui_bridge_stop + 206 5 nvim 0x0000000105fa4c00 ui_builtin_stop + 50 6 nvim 0x0000000105f26ee9 mch_exit + 29 7 nvim 0x0000000105eda84a getout + 518 8 nvim 0x0000000105e778b3 multiqueue_process_events + 77 9 nvim 0x0000000105f24c5a os_breakcheck + 49 10 nvim 0x0000000105eb7ea3 auto_next_pat + 463 11 nvim 0x0000000105eb7603 apply_autocmds_group + 1289 12 nvim 0x0000000105eb0e8d apply_autocmds + 36 13 nvim 0x0000000105f5a412 screenalloc + 1892 14 nvim 0x0000000105f5b223 screen_resize + 190 15 nvim 0x0000000105fa52e3 ui_refresh + 257 16 nvim 0x0000000105e8c3d9 do_cmdline + 6614 17 nvim 0x0000000105f03a72 normal_execute + 3996 18 nvim 0x0000000105f89925 state_enter + 164 19 nvim 0x0000000105efe08d normal_enter + 125 20 nvim 0x0000000105ed9ffd main + 6858 21 libdyld.dylib 0x00007fff67c19115 start + 1 Thread 1 Crashed: 0 libsystem_kernel.dylib 0x00007fff67d68e3e __pthread_kill + 10 1 libsystem_pthread.dylib 0x00007fff67ea7150 pthread_kill + 333 2 libsystem_c.dylib 0x00007fff67cc5312 abort + 127 3 libsystem_c.dylib 0x00007fff67c8d368 __assert_rtn + 320 4 libuv.1.dylib 0x00000001060835bf uv_close + 247 5 nvim 0x0000000105fa0ebb tui_terminal_stop + 221 6 nvim 0x0000000105f9ff3d tui_stop + 14 7 nvim 0x0000000105e778b3 multiqueue_process_events + 77 8 nvim 0x0000000105fa0c89 tui_main + 302 9 libsystem_pthread.dylib 0x00007fff67ea46c1 _pthread_body + 340 10 libsystem_pthread.dylib 0x00007fff67ea456d _pthread_start + 377 11 libsystem_pthread.dylib 0x00007fff67ea3c5d thread_start + 13 TODO: - Set `ui->data = NULL` to flag UI as "stopped"? But loop_poll_events drains *all* fast_events, so could skip some events...
This commit is contained in:
parent
0a4d7ce669
commit
32ad52ae04
@ -316,6 +316,12 @@ static void tui_terminal_after_startup(UI *ui)
|
||||
static void tui_terminal_stop(UI *ui)
|
||||
{
|
||||
TUIData *data = ui->data;
|
||||
if (uv_is_closing(STRUCT_CAST(uv_handle_t, &data->output_handle))) {
|
||||
// Race between SIGCONT (tui.c) and SIGHUP (os/signal.c)? #8075
|
||||
ELOG("TUI already stopped (race?)");
|
||||
ui->data = NULL; // Flag UI as "stopped".
|
||||
return;
|
||||
}
|
||||
term_input_stop(&data->input);
|
||||
signal_watcher_stop(&data->winch_handle);
|
||||
terminfo_stop(ui);
|
||||
@ -325,8 +331,7 @@ static void tui_terminal_stop(UI *ui)
|
||||
static void tui_stop(UI *ui)
|
||||
{
|
||||
tui_terminal_stop(ui);
|
||||
// Flag UI as "stopped".
|
||||
ui->data = NULL;
|
||||
ui->data = NULL; // Flag UI as "stopped".
|
||||
}
|
||||
|
||||
/// Returns true if UI `ui` is stopped.
|
||||
|
Loading…
Reference in New Issue
Block a user