From 1619b2e90e06f9e28fb7b85084e69260b90456d6 Mon Sep 17 00:00:00 2001 From: Shawn Date: Wed, 17 Jun 2026 17:39:01 -0400 Subject: [PATCH] fix: clean stale JACK SHM segments on stop_jack() and at boot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When JACK is killed forcefully (killall -9), the /dev/shm/jack_sem.* shared memory segments and /dev/shm/jack_db-0/ directory are left behind. The next start_jack() call finds these stale segments and fails silently — no audio output, JACK process may appear briefly then crash. Fix: - AudioSystem.stop_jack(): after killing jackd, also rm -rf /dev/shm/jack* to clean up stale SHM. - main.py boot sequence: clean SHM before first start_jack(), so the pedal recovers from crashes that happened before this fix. --- main.py | 13 +++++++++++++ src/system/audio.py | 12 ++++++++++++ 2 files changed, 25 insertions(+) diff --git a/main.py b/main.py index f118ef0..06611e8 100644 --- a/main.py +++ b/main.py @@ -130,6 +130,19 @@ class PedalApp: ) self.audio_system = AudioSystem(self.audio_config) self.audio_system.setup_i2s(reboot_hint=True) + + # Clean stale JACK SHM segments from prior crashes before starting + try: + import shutil + from pathlib import Path + for p in Path("/dev/shm").glob("jack*"): + if p.is_dir(): + shutil.rmtree(p, ignore_errors=True) + else: + p.unlink(missing_ok=True) + except Exception: + pass + if self.audio_config.jack_enabled: self.audio_system.start_jack(timeout=10) else: diff --git a/src/system/audio.py b/src/system/audio.py index 5ed7358..65fe328 100644 --- a/src/system/audio.py +++ b/src/system/audio.py @@ -359,6 +359,18 @@ class AudioSystem: subprocess.run(["killall", "-9", "jackd"], capture_output=True) except FileNotFoundError: pass + # Clean up stale JACK shared memory segments — these prevent a + # new JACK instance from starting if left behind after a crash + # or forceful kill. + try: + import shutil + for p in Path("/dev/shm").glob("jack*"): + if p.is_dir(): + shutil.rmtree(p, ignore_errors=True) + else: + p.unlink(missing_ok=True) + except Exception: + pass def restart_jack(self, timeout: int = 10) -> bool: """Restart JACK server."""