hrkfdn / ncspot

Cross-platform ncurses Spotify client written in Rust, inspired by ncmpc and the likes.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

dump with tmux

Manix80 opened this issue · comments

Describe the bug
dump after closing

To Reproduce
kill tmux with ncspot inside

Expected behavior
do not disturb for the moment, this is just for information :)

System (please complete the following information):

  • OS: Linux archnico 6.5.3-zen1-1-zen
  • Terminal: kitty
  • Version: ncspot 0.13.4 (build in this repo)
  • Installed from: cargo

Backtrace/Debug log
~/.cache/ncspot/backtrace.log :

   0: ncspot::panic::register_backtrace_panic_handler::{{closure}}
   1: <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call
             at /rustc/ec08a0337f3556212525dbf1d3b41e19bdf27621/library/alloc/src/boxed.rs:2021:9
   2: std::panicking::rust_panic_with_hook
             at /rustc/ec08a0337f3556212525dbf1d3b41e19bdf27621/library/std/src/panicking.rs:757:13
   3: std::panicking::begin_panic_handler::{{closure}}
             at /rustc/ec08a0337f3556212525dbf1d3b41e19bdf27621/library/std/src/panicking.rs:631:13
   4: std::sys_common::backtrace::__rust_end_short_backtrace
             at /rustc/ec08a0337f3556212525dbf1d3b41e19bdf27621/library/std/src/sys_common/backtrace.rs:170:18
   5: rust_begin_unwind
             at /rustc/ec08a0337f3556212525dbf1d3b41e19bdf27621/library/std/src/panicking.rs:619:5
   6: core::panicking::panic_fmt
             at /rustc/ec08a0337f3556212525dbf1d3b41e19bdf27621/library/core/src/panicking.rs:72:14
   7: core::result::unwrap_failed
             at /rustc/ec08a0337f3556212525dbf1d3b41e19bdf27621/library/core/src/result.rs:1652:5
   8: core::ptr::drop_in_place<termion::raw::RawTerminal<std::io::buffered::bufwriter::BufWriter<std::fs::File>>>
   9: core::ptr::drop_in_place<core::cell::RefCell<termion::screen::AlternateScreen<termion::input::MouseTerminal<termion::raw::RawTerminal<std::io::buffered::bufwriter::BufWriter<std::fs::File>>>>>>
  10: core::ptr::drop_in_place<cursive::backends::termion::Backend>
  11: core::ptr::drop_in_place<cursive_buffered_backend::BufferedBackend>
  12: core::ptr::drop_in_place<cursive_core::cursive_run::CursiveRunner<cursive_core::cursive::Cursive>>
  13: ncspot::main
  14: std::sys_common::backtrace::__rust_begin_short_backtrace
  15: main
  16: <unknown>
  17: __libc_start_main
  18: _start

panicked at /home/nico/.local/share/cargo/registry/src/index.crates.io-6f17d22bba15001f/termion-1.5.6/src/raw.rs:45:43:
called `Result::unwrap()` on an `Err` value: Os { code: 5, kind: Uncategorized, message: "Input/output error" }

Additional context
everything works perfectly, the only peculiarity is that I launch ncspot in tmux which, once destroyed, produces a dump.

I can definitely reproduce this using Zellij as the terminal multiplexer by terminating the session. I haven't tried killing it with a SIGKILL. For a more minimal example, it also works without a multiplexer by closing the terminal while ncspot is running (tested in both Alacritty and GNOME Terminal). Seems like an interesting bug. I want to look into this for a bit 😄

From what I can see, this is caused by the backend trying to return from the alternate screen by writing a command to /dev/tty which isn't available anymore somehow. Cursive implements this for the ncurses backend which is why the bug appears to be in cursive with that backend. termion implements this by itself which is why the bug appears to be in the termion crate with that backend. Same for the other backends probably.

Backtrace (Termion backend, v0.13.2 from Arch extra repo):

   0: <unknown>
   1: <unknown>
   2: <unknown>
   3: <unknown>
   4: <unknown>
   5: <unknown>
   6: <unknown>
   7: <unknown>
   8: <unknown>
   9: <unknown>
  10: <unknown>
  11: <unknown>
  12: <unknown>
  13: <unknown>
  14: <unknown>
  15: main
  16: <unknown>
  17: __libc_start_m
  18: <un<unkno
  19: <unknown>
  20: <unknown>
  21: <unknown>
  22: <unknown>

panicked at 'all branches are disabled and there is no else branch', src/mpris.rs:516:13
src/github.com-1ecc6299db9ec823/termion-1.5.6/src/raw.rs:45:43

Backtrace (ncurses backend, v0.13.4 from cargo):

   0: ncspot::panic::register_backtrace_panic_handler::{{closure}}
   1: <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/alloc/src/boxed.rs:2007:9
   2: std::panicking::rust_panic_with_hook
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:709:13
   3: std::panicking::begin_panic_handler::{{closure}}
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:597:13
   4: std::sys_common::backtrace::__rust_end_short_backtrace
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/sys_common/backtrace.rs:151:18
   5: rust_begin_unwind
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:593:5
   6: core::panicking::panic_fmt
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/panicking.rs:67:14
   7: core::result::unwrap_failed
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/result.rs:1651:5
   8: cursive::backends::curses::n::write_to_tty
   9: core::ptr::drop_in_place<cursive::backends::curses::n::Backend>
  10: core::ptr::drop_in_place<cursive_buffered_backend::BufferedBackend>
  11: core::ptr::drop_in_place<cursive_core::cursive_run::CursiveRunner<cursive_core::cursive::Cursive>>
  12: ncspot::main
  13: std::sys_common::backtrace::__rust_begin_short_backtrace
  14: main
  15: <unknown>
  16: __libc_start_main
  17: _start

panicked at 'cursive can only run with a tty: Os { code: 6, kind: Uncategorized, message: "No such device or address" }', /home/thomas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cursive-0.20.0/src/backends/curses/n.rs:55:34

Ah nice detective work, I've just switched to crossterm by default in main, would be curious to know if the problem occurs there as well.

Backtrace (Crossterm backend, main branch with cargo run)

   0: ncspot::panic::register_backtrace_panic_handler::{{closure}}
             at ./src/panic.rs:20:38
   1: <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/alloc/src/boxed.rs:2007:9
   2: std::panicking::rust_panic_with_hook
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:709:13
   3: std::panicking::begin_panic_handler::{{closure}}
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:597:13
   4: std::sys_common::backtrace::__rust_end_short_backtrace
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/sys_common/backtrace.rs:151:18
   5: rust_begin_unwind
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:593:5
   6: core::panicking::panic_fmt
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/panicking.rs:67:14
   7: core::result::unwrap_failed
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/result.rs:1651:5
   8: core::result::Result<T,E>::expect
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/result.rs:1033:23
   9: <cursive::backends::crossterm::Backend as core::ops::drop::Drop>::drop::{{closure}}
             at /home/thomas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cursive-0.20.0/src/backends/crossterm.rs:297:13
  10: cursive::backends::crossterm::Backend::with_stdout
             at /home/thomas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cursive-0.20.0/src/backends/crossterm.rs:244:9
  11: <cursive::backends::crossterm::Backend as core::ops::drop::Drop>::drop
             at /home/thomas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cursive-0.20.0/src/backends/crossterm.rs:296:9
  12: core::ptr::drop_in_place<cursive::backends::crossterm::Backend>
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/ptr/mod.rs:497:1
  13: core::ptr::drop_in_place<alloc::boxed::Box<dyn cursive_core::backend::Backend>>
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/ptr/mod.rs:497:1
  14: core::ptr::drop_in_place<cursive_buffered_backend::BufferedBackend>
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/ptr/mod.rs:497:1
  15: core::ptr::drop_in_place<alloc::boxed::Box<dyn cursive_core::backend::Backend>>
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/ptr/mod.rs:497:1
  16: core::ptr::drop_in_place<cursive_core::cursive_run::CursiveRunner<cursive_core::cursive::Cursive>>
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/ptr/mod.rs:497:1
  17: core::ptr::drop_in_place<ncspot::application::Application>
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/ptr/mod.rs:497:1
  18: ncspot::main
             at ./src/main.rs:66:1
  19: core::ops::function::FnOnce::call_once
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/ops/function.rs:250:5
  20: std::sys_common::backtrace::__rust_begin_short_backtrace
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/sys_common/backtrace.rs:135:18
  21: std::rt::lang_start::{{closure}}
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/rt.rs:166:18
  22: core::ops::function::impls::<impl core::ops::function::FnOnce<A> for &F>::call_once
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/ops/function.rs:284:13
  23: std::panicking::try::do_call
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:500:40
  24: std::panicking::try
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:464:19
  25: std::panic::catch_unwind
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panic.rs:142:14
  26: std::rt::lang_start_internal::{{closure}}
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/rt.rs:148:48
  27: std::panicking::try::do_call
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:500:40
  28: std::panicking::try
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:464:19
  29: std::panic::catch_unwind
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panic.rs:142:14
  30: std::rt::lang_start_internal
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/rt.rs:148:20
  31: std::rt::lang_start
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/rt.rs:165:17
  32: main
  33: <unknown>
  34: __libc_start_main
  35: _start

panicked at 'Can not disable mouse capture or show cursor.: Os { code: 5, kind: Uncategorized, message: "Input/output error" }', /home/thomas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/cursive-0.20.0/src/backends/crossterm.rs:298:18
o-6f17d22bba15001f/tokio-1.32.0/src/runtime/context.rs:176:26
  32: std::thread::local::LocalKey<T>::try_with
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/thread/local.rs:270:16
  33: std::thread::local::LocalKey<T>::with
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/thread/local.rs:246:9
  34: tokio::runtime::context::set_scheduler
             at /home/thomas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/context.rs:176:9
  35: tokio::runtime::scheduler::multi_thread::worker::run::{{closure}}
             at /home/thomas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/scheduler/multi_thread/worker.rs:486:9
  36: tokio::runtime::context::runtime::enter_runtime
             at /home/thomas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/context/runtime.rs:65:16
  37: tokio::runtime::scheduler::multi_thread::worker::run
             at /home/thomas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/scheduler/multi_thread/worker.rs:478:5
  38: tokio::runtime::scheduler::multi_thread::worker::Launch::launch::{{closure}}
             at /home/thomas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/scheduler/multi_thread/worker.rs:447:45
  39: <tokio::runtime::blocking::task::BlockingTask<T> as core::future::future::Future>::poll
             at /home/thomas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/blocking/task.rs:42:21
  40: tokio::runtime::task::core::Core<T,S>::poll::{{closure}}
             at /home/thomas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/task/core.rs:334:17
  41: tokio::loom::std::unsafe_cell::UnsafeCell<T>::with_mut
             at /home/thomas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/loom/std/unsafe_cell.rs:16:9
  42: tokio::runtime::task::core::Core<T,S>::poll
             at /home/thomas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/task/core.rs:323:13
  43: tokio::runtime::task::harness::poll_future::{{closure}}
             at /home/thomas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/task/harness.rs:485:19
  44: <core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/panic/unwind_safe.rs:271:9
  45: std::panicking::try::do_call
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:500:40
  46: __rust_try
  47: std::panicking::try
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:464:19
  48: std::panic::catch_unwind
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panic.rs:142:14
  49: tokio::runtime::task::harness::poll_future
             at /home/thomas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/task/harness.rs:473:18
  50: tokio::runtime::task::harness::Harness<T,S>::poll_inner
             at /home/thomas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/task/harness.rs:208:27
  51: tokio::runtime::task::harness::Harness<T,S>::poll
             at /home/thomas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/task/harness.rs:153:15
  52: tokio::runtime::task::raw::poll
             at /home/thomas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/task/raw.rs:276:5
  53: tokio::runtime::task::raw::RawTask::poll
             at /home/thomas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/task/raw.rs:200:18
  54: tokio::runtime::task::UnownedTask<S>::run
             at /home/thomas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/task/mod.rs:437:9
  55: tokio::runtime::blocking::pool::Task::run
             at /home/thomas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/blocking/pool.rs:159:9
  56: tokio::runtime::blocking::pool::Inner::run
             at /home/thomas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/blocking/pool.rs:513:17
  57: tokio::runtime::blocking::pool::Spawner::spawn_thread::{{closure}}
             at /home/thomas/.cargo/registry/src/index.crates.io-6f17d22bba15001f/tokio-1.32.0/src/runtime/blocking/pool.rs:471:13
  58: std::sys_common::backtrace::__rust_begin_short_backtrace
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/sys_common/backtrace.rs:135:18
  59: std::thread::Builder::spawn_unchecked_::{{closure}}::{{closure}}
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/thread/mod.rs:529:17
  60: <core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/panic/unwind_safe.rs:271:9
  61: std::panicking::try::do_call
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:500:40
  62: __rust_try
  63: std::panicking::try
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panicking.rs:464:19
  64: std::panic::catch_unwind
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/panic.rs:142:14
  65: std::thread::Builder::spawn_unchecked_::{{closure}}
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/thread/mod.rs:528:30
  66: core::ops::function::FnOnce::call_once{{vtable.shim}}
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/core/src/ops/function.rs:250:5
  67: <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/alloc/src/boxed.rs:1993:9
  68: <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/alloc/src/boxed.rs:1993:9
  69: std::sys::unix::thread::Thread::new::thread_start
             at /rustc/d5c2e9c342b358556da91d61ed4133f6f50fc0c3/library/std/src/sys/unix/thread.rs:108:17
  70: <unknown>
  71: <unknown>

panicked at 'all branches are disabled and there is no else branch', src/mpris.rs:516:13

I thought this commit would have settled the matter:
a69e2d7

new backtrace if that helps.

 0: ncspot::panic::register_backtrace_panic_handler::{{closure}}
  1: <alloc::boxed::Box<F,A> as core::ops::function::Fn<Args>>::call
            at /rustc/475c71da0710fd1d40c046f9cee04b733b5b2b51/library/alloc/src/boxed.rs:2021:9
  2: std::panicking::rust_panic_with_hook
            at /rustc/475c71da0710fd1d40c046f9cee04b733b5b2b51/library/std/src/panicking.rs:735:13
  3: std::panicking::begin_panic_handler::{{closure}}
            at /rustc/475c71da0710fd1d40c046f9cee04b733b5b2b51/library/std/src/panicking.rs:601:13
  4: std::sys_common::backtrace::__rust_end_short_backtrace
            at /rustc/475c71da0710fd1d40c046f9cee04b733b5b2b51/library/std/src/sys_common/backtrace.rs:170:18
  5: rust_begin_unwind
            at /rustc/475c71da0710fd1d40c046f9cee04b733b5b2b51/library/std/src/panicking.rs:597:5
  6: core::panicking::panic_fmt
            at /rustc/475c71da0710fd1d40c046f9cee04b733b5b2b51/library/core/src/panicking.rs:72:14
  7: core::panicking::panic
            at /rustc/475c71da0710fd1d40c046f9cee04b733b5b2b51/library/core/src/panicking.rs:127:5
  8: ncspot::application::Application::new::{{closure}}
  9: tokio::runtime::task::raw::poll
 10: tokio::runtime::scheduler::multi_thread::worker::Context::run_task
 11: tokio::runtime::task::raw::poll
 12: std::sys_common::backtrace::__rust_begin_short_backtrace
 13: core::ops::function::FnOnce::call_once{{vtable.shim}}
 14: <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once
            at /rustc/475c71da0710fd1d40c046f9cee04b733b5b2b51/library/alloc/src/boxed.rs:2007:9
 15: <alloc::boxed::Box<F,A> as core::ops::function::FnOnce<Args>>::call_once
            at /rustc/475c71da0710fd1d40c046f9cee04b733b5b2b51/library/alloc/src/boxed.rs:2007:9
 16: std::sys::unix::thread::Thread::new::thread_start
            at /rustc/475c71da0710fd1d40c046f9cee04b733b5b2b51/library/std/src/sys/unix/thread.rs:108:17
 17: <unknown>
 18: <unknown>

panicked at src/application.rs:74:18:
internal error: entered unreachable code

also remains in the background.
(fresh main build)

No, main is a bit broken for the moment. A real fix for this issue will probably be done this weekend, maybe later than that. For now it's best to use a release version like v0.13.4 which still has the dump problem but doesn't stay open in the background. The commit you mentioned is unrelated. It just disables tracing logs for a particular crate that were cluttering up the debug logs.

These are the PRs that will close these issues: #1305 #1299 #1310

@ThomasFrans I think you are onto something w.r.t this:

From what I can see, this is caused by the backend trying to return from the alternate screen by writing a command to /dev/tty which isn't available anymore somehow. Cursive implements this for the ncurses backend which is why the bug appears to be in cursive with that backend. termion implements this by itself which is why the bug appears to be in the termion crate with that backend. Same for the other backends probably.

I'm wondering if the .expect in the backend implementation should be changed to not panic: https://github.com/gyscos/cursive/blob/3b0e329eb5f39a0eba7330285c740d8a7a660cad/cursive/src/backends/crossterm.rs#L311-L322

Maybe it's doing the exit/ backend cleanup logic twice or something, as I can't reproduce this with a test application that doesn't call Cursive::quit() on SIGHUP.

The dump mentioned in this issue seems to be caused by /dev/tty being closed before cursive got the chance to clean up, resulting in a panic as it can't write the cleanup commands to the terminal. What's weird is that with the async task (and without the Crossterm backend), I wasn't having any issues anymore. I don't know what changed as I mostly copied the code from the event loop over to the async task and sent signals to cursive through the CbSink. Since the async version did solve this issue, I somehow believe that the real problem is with how signals are handled currently.

To solve this issue, I would personally consider changing the default backend to ncurses and going with the async version as it feels like the most 'correct' way to handle signals and has worked as long as the Crossterm backend isn't used. Signals can arrive at any point in time, which makes a dedicated task the most natural approach.

As for the problem with Crossterm, I would consider switching to the ncurses backend as it's the most mature TUI library and currently the most actively maintained one. All the others haven't seen much activity in a few months. Some haven't been touched in over a year. I would also consider removing the crossterm_backend feature altogether as it's broken and shouldn't be used until it gets fixed upstream.

I'm a big fan of using Rust for everything (#RIIR 😝), and using a C library to handle the TUI is a bit annoying, but I think it will prevent a lot of issues from being opened that are caused by problems upstream that can't be fixed here or would have to be fixed with a hacked together workaround.

Would love some input on these ideas as I'm just brainstorming here. There could be other, better approaches to the problem. Ultimately it would be best to find a solution that prevents problems with the TUI in the future and would provide users with the most stable experience.

ncurses would be the reasonable choice and I was looking into this today, but unfortunately the ncurses backend has its own problems such as 256 colors not working correctly.

Maybe turn ncspot into a daemon and only support MPRIS. No more TUI, no more problems 😅

I'm going to sound like I'm making jokes here but I have a serious proposal.

Cursive has 5 available backends:

  • BearLibTerminal: abandoned
  • Crossterm: abandoned (its maintainer seems to be busy with another project)
  • Ncurses: bad 256 color support
  • Pancurses: abandoned
  • Termion: maybe abandoned, problems with certain keys like Shift+Up/Down

So, why not support ncurses and maybe termion as they are both probably maintained, and fork the best one of the other libraries (termion, crossterm or pancurses as they are written in Rust). Of course this would mean that ncspot now has to maintain it, BUT they aren't maintained anyway so might as well fork them and do some tiny fixes when problems occur. We'd have to implement the cursive::Backend trait (which would just mean copy it from cursive as there will be no difference except for the name maybe). If there are updates to the upstream versions, they could be merged to the fork, and when they become actively maintained again, ncspot could depend on them and drop the fork.

I think it would make sense as well as ncspot needs a TUI library anyway and is currently already using unmaintained ones. The situation can only improve, and this way other Rust apps that need a 'maintained' TUI crate could optionally benefit from this as well.

Of course I'm also brainstorming again, and of course I would be willing to do the changes needed for this, but to me this sounds like a reasonable solution to the dependency on unmaintained TUI crates.

I appreciate your proposal. Some thoughts from my side:

I have to say that I myself currently don't have the time to maintain a terminal backend, that shouldn't stop you though! It's also not the easiest field to navigate with all the different platforms, terminal emulators, etc. to support. But if you are interested in the project, I'd say go for it!

I'm not sure it would have to be under the umbrella of ncspot as ncspot is terminal-backend agnostic. Maybe it makes sense to align with the Cursive project if you'd like to add support for that backend upstream as well?

I'm going to think a bit further about the best approach to solve the TUI related problems. I definitely don't want to maintain a terminal library. I'd only do minimal bugfixes, which would be an improvement over using a library that's abandoned, but there might be other approaches as well. I'll sleep on it for a bit.