From 586d7950cf48c63d283df8896e9e2351833e5e76 Mon Sep 17 00:00:00 2001 From: sudacode Date: Wed, 28 Oct 2026 19:54:04 -0700 Subject: [PATCH] fix(appimage): check mount exe links one at a time for uutils - uutils readlink (Ubuntu 26.04+) aborts at the first unreadable /proc//exe, so the keepalive released the mount early - Add mount_busy helper that readlinks each link individually - Add changelog fragment --- changes/appimage-keepalive-uutils.md | 4 ++++ src/main/appimage-mount-keepalive.ts | 12 +++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) create mode 100644 changes/appimage-keepalive-uutils.md diff --git a/changes/appimage-keepalive-uutils.md b/changes/appimage-keepalive-uutils.md new file mode 100644 index 00000000..408c3f76 --- /dev/null +++ b/changes/appimage-keepalive-uutils.md @@ -0,0 +1,4 @@ +type: fixed +area: linux + +- Fixed AppImage builds on Ubuntu 26.04+ (uutils coreutils) releasing their mount before Chromium child processes finished shutting down, which brought back "Service Crash" notifications on quit. diff --git a/src/main/appimage-mount-keepalive.ts b/src/main/appimage-mount-keepalive.ts index 02f76bc8..3db5b726 100644 --- a/src/main/appimage-mount-keepalive.ts +++ b/src/main/appimage-mount-keepalive.ts @@ -52,13 +52,23 @@ if [ -z "$app_run" ]; then kill "$holder" 2>/dev/null run_direct "$@" fi +# One readlink per link: uutils readlink (Ubuntu 26.04+) aborts at the first +# unreadable operand, and other users' /proc//exe are always unreadable. +mount_busy() { + for exe in /proc/[0-9]*/exe; do + case "$(readlink "$exe" 2>/dev/null)" in + "$mount_point"/*) return 0 ;; + esac + done + return 1 +} APPDIR="$mount_point" "$app_run" "$@" rc=$? # Do not release the mount while any process still executes from it; releasing # early SIGBUSes Chromium children that are mid-shutdown. tries=0 while [ "$tries" -lt 100 ]; do - if readlink /proc/[0-9]*/exe 2>/dev/null | grep -qF "$mount_point/"; then + if mount_busy; then sleep 0.1 tries=$((tries + 1)) else