Skip to content

Crash: use-after-free in AudioEngine::onTxAudioReady after long runtime (macOS) #1149

Description

@pepefrog1234

Bug Report

Environment

  • OS: macOS 26.3.1 (25D771280a) / ARM-64 (Mac Studio, Mac16,9)
  • AetherSDR: v0.8.7
  • Qt: 6.11

Description

AetherSDR crashes after ~16 hours of continuous operation. The crash occurs in the AudioEngine thread when onTxAudioReady() accesses a dangling QIODevice pointer (m_micBuffer).

Crash Summary

Thread 6 Crashed:: AudioEngine
Exception Type:    EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x00000000001eaa91

0   QtCore    QIODevice::isOpen() const + 4
1   AetherSDR 0x102159594  (onTxAudioReady, offset 349588)
2   QtCore    QTimer::timerEvent(QTimerEvent*) + 216

Analysis

The crash address 0x1eaa91 is a very low address, consistent with a use-after-free (null pointer + struct offset dereference). The m_micBuffer (QBuffer) appears to have been freed but the pointer was not set to nullptr. The 5ms TX poll timer continues to fire and onTxAudioReady() dereferences the stale pointer.

Likely sequence:

  1. After ~16 hours, QAudioSource silently stops (known Qt6/macOS behavior)
  2. This triggers cleanup that deletes m_micBuffer
  3. The TX poll timer is still running
  4. Next timer tick calls onTxAudioReady() → accesses freed m_micBuffer → SIGSEGV

Suggested Fix

In stopTxStream() (or wherever m_micBuffer is destroyed):

  1. Stop m_txPollTimer before deleting m_micBuffer
  2. Set m_micBuffer = nullptr after deletion
  3. Consider monitoring QAudioSource::stateChanged for auto-recovery after silent stops

Runtime Details

  • Launch: 2026-04-10 05:33:20
  • Crash: 2026-04-10 21:51:20
  • Uptime: ~16 hours 18 minutes

Full Crash Report

Thread 6 (AudioEngine) stack trace
Thread 6 Crashed:: AudioEngine
0   QtCore   QIODevice::isOpen() const + 4
1   AetherSDR  0x102159594 (offset 349588)
2   QtCore     0x106ea93e8
3   QtCore     QTimer::timerEvent(QTimerEvent*) + 216
4   QtCore     QObject::event(QEvent*) + 668
5   QtWidgets  QApplicationPrivate::notify_helper(QObject*, QEvent*) + 336
6   QtWidgets  QApplication::notify(QObject*, QEvent*) + 468
7   QtCore     QCoreApplication::sendEvent(QObject*, QEvent*) + 168
8   QtCore     QTimerInfoList::activateTimers() + 1316
9   QtCore     QEventDispatcherUNIX::processEvents(...) + 1288
10  QtCore     QEventLoop::exec(...) + 588
11  QtCore     QThread::exec() + 348

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions