Skip to content

[Bug]: Linux — every quit ends in SIGABRT (TLS destructor panic), reproduces on 0.19.0 / 0.19.2 / 0.19.4 #336

Description

@hadyandev

Environment: Navop 0.19.4 (AUR navop-bin) on Omarchy 4.0.4 / Arch, Wayland + Hyprland 0.56.2 — also reproduced on 0.19.0 and 0.19.2.

1. What happened?

Every in-app quit on Linux ends in SIGABRT plus a core dump, on all three versions I have tried (0.19.0, 0.19.2 from the release tarball, and 0.19.4).

The shutdown itself completes normally first — the log shows the SSH/RDP session services finishing with confirmed application quit and all database sessions disconnecting — and only after that does the process abort. So there is no data loss: PRAGMA integrity_check on ~/.config/navop/one-hub.db returns ok. The cost is that systemd records every ordinary quit as a crash: the desktop's crash watcher (Omarchy's omarchy-crash-watch, which announces systemd-coredump journal entries) toasts "Process crashed: navop" on every single close, and 3-6 MB cores accumulate.

The panic is in libstd's TLS destructor path, i.e. it happens after main has returned:

thread 'main' (194045) panicked at library/std/src/thread/local.rs:429:25:
cannot access a Thread Local Storage value during or after destruction: AccessError
abort <- raise <- [navop] <- __call_tls_dtors <- exit <- __libc_start_main

kill -TERM is the only exit that does not abort: the process dies immediately, runs no destructors and writes no core. Every exit the application performs itself aborts.

2. How can we reproduce it?

It reproduced 9 times out of 9 core files across sessions; a scripted route that needs no clicking:

  1. Launch Navop and wait for the tray icon.

  2. Read the tray item's menu (退出 Navop is item id 3):

    dbus-send --session --print-reply \
      --dest=org.kde.StatusNotifierItem-<pid>-1 /MenuBar \
      com.canonical.dbusmenu.GetLayout int32:0 int32:-1 array:string:
  3. Click that item:

    dbus-send --session --print-reply \
      --dest=org.kde.StatusNotifierItem-<pid>-1 /MenuBar \
      com.canonical.dbusmenu.Event int32:3 string:"clicked" variant:string:"" uint32:0
  4. The process exits with SIGABRT and leaves a core: coredumpctl list navop gains an entry, every time.

The same happens through the GUI: click the window's close button and choose Quit in the "Close Navop?" dialog.

3. Version and system

Navop 0.19.4 (AUR navop-bin) — also reproduced on 0.19.0 (AUR) and 0.19.2 (navop-0.19.2-linux-x64.tar.gz, sha256 matched the release sha256sums.txt)
Distro Omarchy 4.0.4 (Arch-based), kernel 7.2.5-3-omarchy
Session Wayland, Hyprland 0.56.2
glibc / systemd glibc 2.44, systemd 261.2
GPU AMD Radeon 680M iGPU (RADV REMBRANDT), Vulkan backend selected
Binary /usr/bin/navop, stripped, no build-id (Module navop without build-id.), so users can only report code offsets

4. Logs and anything else

Log tail of a normal quit — the shutdown lines land first, the abort comes after them:

INFO navop::navop_app: Windows native RDP shutdown completed reason="confirmed application quit" requested=0 destroyed=0
INFO navop::navop_app: SSH session service shutdown completed reason="confirmed application quit" managers_requested=0 managers_completed=0
INFO navop::navop_app: Windows native RDP shutdown completed reason="gpui quit fallback" requested=0 destroyed=0
INFO navop::navop_app: SSH session service shutdown completed reason="gpui quit fallback" managers_requested=0 managers_completed=0

coredumpctl info <pid> for the 0.19.4 run:

Signal: 6 (ABRT) si_code: SI_TKILL
Command Line: /usr/bin/navop
    Module navop without build-id.
    Stack trace of thread <pid>:
    #15 __call_tls_dtors (libc.so.6 + 0x40bfa)
    #19 __libc_start_main (libc.so.6 + 0x278b9)

Frequency so far: 12 SIGABRT journal entries (9 of them with a core file written) spread over 0.19.0, 0.19.2 and 0.19.4 — in every case the trigger was the app's own quit path, never an external signal.

Extra analysis (from the reporter, not a diagnosis)

  • Everything points at teardown order: a thread-local is read after its destructor has already run. The failing frame returns into navop itself; the shipped binary is stripped and carries no build-id, so the exact function cannot be resolved from the core — a symbol map or an unstripped debug artifact would pin it.
  • On this machine Navop logs a hotkey conflict at startup (navop::app_init::system_hotkey: ... AlreadyRegistered(ALT|CONTROL + KeyM), the hotkey is ctrl-alt-m), and the core contains both hyprland_global_shortcuts_manager_v1 and vicinae_hotkey_manager_v1. A global-shortcut/hotkey manager is a plausible owner of a thread-local touched during teardown — this is a suspicion, not a finding.
  • The 0.19.4 notes describe a macOS fix of the same shape (keep the native window, hide instead of destroy, on close). Linux still destroys on close.
  • Downstream workarounds I am using meanwhile, neither of which is a fix: silencing the crash watcher's announcement for this process, and disabling core dumps for it.
  • I can attach the cores (~3.6-6 MB each, systemd-coredump format) or test a candidate patch on this machine.

Activity

  1. feigeCode commented on Oct 7, 2026

    @feigeCode
    Owner

    最新版本试试

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions