Skip to content

Crash on quit — TciServer::releaseDaxForTci() dereferences null/dangling RadioModel during MainWindow teardown #2385

@vu2cpl

Description

@vu2cpl

Title: Crash on quit — TciServer::releaseDaxForTci() dereferences null/dangling RadioModel during MainWindow teardown

Version: AetherSDR 0.9.5.1 (0.9.5.1) / Same issue is there on 0.9.96 also
Platform: macOS 26.3.1 (build 25D771280a), Apple Silicon (Mac16,11 / M4 Pro), 24 GB
Bundle ID: com.aethersdr.AetherSDR
Frequency: Reproducible on application quit


Summary

AetherSDR crashes on the main thread during normal application shutdown. The crash occurs after main begins returning and ~MainWindow() is executing. There is no user-visible impact during runtime — the crash dialog only appears when quitting the app. A FLEX-6600 was connected during the session.

Exception

Exception Type:    EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000038
Triggered by:      Thread 0 (com.apple.main-thread)

Fault address 0x38 and x8 = 0x38 strongly indicate a member-field read through a null or dangling this pointer (offset 0x38 = 56 bytes into the object).

Crashing call stack (top frames)

0  AetherSDR  AetherSDR::RadioModel::isConnected() const + 8
1  AetherSDR  AetherSDR::TciServer::releaseDaxForTci() + 364
2  AetherSDR  AetherSDR::TciServer::stop() + 596
3  AetherSDR  AetherSDR::TciServer::~TciServer() + 40
4  AetherSDR  AetherSDR::TciServer::~TciServer() + 12
5  QtCore     QObjectPrivate::deleteChildren() + 156
6  QtWidgets  QWidget::~QWidget() + 1188
7  AetherSDR  AetherSDR::MainWindow::~MainWindow() + 2348
8  AetherSDR  main + 3152
9  dyld       start + 7184

Suspected root cause

QObject parent/child destruction order: by the time ~TciServer runs as part of MainWindow's child cleanup, the RadioModel it depends on has already been destroyed (or was never a Qt-tracked pointer). TciServer::stop() unconditionally calls releaseDaxForTci(), which in turn calls RadioModel::isConnected() on the stale pointer.

Suggested fix

One of the following on TciServer's side:

  1. Hold the RadioModel* as a QPointer<RadioModel> and null-check before use in releaseDaxForTci() / stop().
  2. Explicitly tear down TciServer (or call stop() on it) early in ~MainWindow before RadioModel is destroyed, rather than relying on QObject child-deletion order.
  3. Make releaseDaxForTci() defensive — early-return if the radio model is null or already disconnected.

Reproduction

  1. Launch AetherSDR 0.9.5.1 on macOS 26.3.1 / Apple Silicon
  2. Connect to FlexRadio (FLEX-6600 in my case) over the network
  3. (Optional) Enable TCI server
  4. Quit the application — crash on exit

Crash report identifiers

  • Incident Identifier: 3289515E-9E9E-4C7F-AA67-EDA6F980A2FD
  • Crash Reporter Key: A05BED7F-F26D-1DDD-EB31-F7039C806467
  • Slice UUID: 2943cb76-d320-392d-a2a1-e8c2b297bded
  • Capture time: 2026-05-05 22:16:35 +0530

Full .crash / .ips available on request.

73,
Manoj — VU2CPL

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingmaintainer-reviewRequires maintainer review before any action is takenpriority: highHigh priorityprotocolSmartSDR protocol

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions