Guard audio callbacks during shutdown#2413
Conversation
There was a problem hiding this comment.
Pull request overview
This PR prevents a shutdown-time crash caused by TX-state Qt signal callbacks calling into AudioEngine after MainWindow has already torn down the audio worker and set m_audio to nullptr.
Changes:
- Add
m_audionull guards in theTransmitModel::moxChangedcallback before callingAudioEngine::setTransmitting()/AudioEngine::setRadeMode(). - Add
m_audionull guards in theRadioModel::txAudioGateChangedcallback before forcing TX-off audio state. - Add
m_audionull guards in theRadioModel::radioTransmittingChangedcallback before callingAudioEngine::setRadioTransmitting(), while preserving non-audio UI updates (waterfall/status).
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
Hi @rfoust — thanks for putting this together! Wanted to flag what's happening with the red ❌ before you spend any time digging. TL;DR — this isn't your codeThe only failed check is Cleanup artifacts, and the failing step is Delete artifacts (job log). That's a teardown step in our agent-review workflow that runs after the actual review work is done. The substantive jobs in that run all passed:
This is a known intermittent on the GitHub artifacts API (rate limit / 5xx from Heads up: the real build is still runningThe two checks that matter for merge — One small note while you're here: each of the three lambdas only changes if Thanks again for taking the time on this — these are exactly the kind of crash-prevention guards that pay off when the audio backend hasn't initialized yet on a slow connect path. 🎯 |
|
Claude here — really good crash report, Robbie. Walking through the destruction order to nail the QObject auto-disconnect timing was the key insight. The per-call-site guards (including separating the inner RADE guard from the outer) match the file's existing pattern cleanly. Merged. 73, Jeremy KK7GWY & Claude (AI dev partner) |
Summary
m_audioafter the audio worker has already been torn down.m_audiois null.Crash
The reported macOS crash happened while exiting the app. During
MainWindowteardown the audio worker is stopped andm_audiois set tonullptr. Later in member destruction,WanConnection::~WanConnection()disconnects the TLS socket, which emitsdisconnected, drivesRadioModel::onDisconnected(), and emitsradioTransmittingChanged(false)/ related TX reset signals. The connectedMainWindowlambdas still ran and called methods such asm_audio->setRadioTransmitting(tx), so the app enteredAudioEngine::setRadioTransmitting()with an invalid/nullthispointer and crashed on the atomic exchange shown in the report.Fix
Add null guards around the audio calls in the TX-state callbacks (
moxChanged,txAudioGateChanged, andradioTransmittingChanged). This preserves the existing shutdown order, object ownership, signal routing, and non-audio UI updates, while avoiding calls into the audio worker after it has been destroyed.Verification
cmake -B build -G Ninja -DCMAKE_BUILD_TYPE=RelWithDebInfocmake --build buildgit diff --check