kitlangton / kitlangton/Hex

Crash on app quit / background: use-after-free in AVAudioEngine teardown (EXC_BAD_ACCESS)

Open
#245 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Swift
Stars
2.9k
Forks
226
PR merge metrics
No merged PRs in 30d

Description

**Describe the bug**

Hex crashes with a segmentation fault (EXC_BAD_ACCESS) when the audio engine is being torn down — either on app quit or when transitioning to background. The crash is a use-after-free: an AVAudioIOUnit property listener callback fires on the `AVAudioIOUnit` dispatch queue after the `AVAudioEngine` object has already been deallocated.

**Exception Details**

- **Type:** EXC_BAD_ACCESS (SIGSEGV)
- **Subtype:** KERN_INVALID_ADDRESS (possible pointer authentication failure)
- **Crashed Thread:** Thread 12, Dispatch Queue: `AVAudioIOUnit`
- **Crash Frame:** `objc_msgSend` called from `AVAudioIOUnit::IOUnitPropertyListener` block

**Crash Stack (Thread 12 - Crashed)**

```
0 libobjc.A.dylib objc_msgSend + 32
1 AVFAudio invocation function for block in AVAudioIOUnit::IOUnitPropertyListener
2 libdispatch.dylib _dispatch_call_block_and_release
...
```

**Root Cause**

Thread 11 is tearing down `AVAudioEngine` (dealloc). Inside the dealloc, `AUAudioUnitV2Bridge::invalidateAudioUnit` drains the caulk messenger, which destroys a semaphore still in use by the IOUnit property listener callback on Thread 12. The listener then fires `objc_msgSend` on a freed `AVAudioEngine` reference.

**To Reproduce**

Not consistently reproducible, but the crash occurs under these conditions:
1. Use Hex to transcribe (audio engine is active)
2. Quit the app, or let it transition to background state
3. Crash during engine teardown

The crash is a race condition in the teardown ordering — the IOUnit property listener outlives the engine it belongs to.

**Expected behavior**

Hex should quit or background gracefully without crashing. The audio engine should be stopped and all listeners unregistered before the engine reference is released.

**Desktop (please complete the following information):**

- Version: 0.7.6 (86)
- macOS: 26.5.1 (25F80)
- Hardware: MacBookPro18,1 (Apple M1 Pro)

**Crash Report**

Full crash report attached:

```
Process: Hex [72453]
Path: /Applications/Hex.app/Contents/MacOS/Hex
Identifier: com.kitlangton.Hex
Version: 0.7.6 (86)
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Subtype: KERN_INVALID_ADDRESS at 0x007975f6cb171e10
Triggered by Thread: 12, Dispatch Queue: AVAudioIOUnit
```

Contributor guide

No contributing guide indexed for this repository

Research direction

Start by tracing the AVAudioEngine lifecycle during transcription, app quit, and background transitions, focusing on the AVAudioIOUnit property listener and teardown ordering described in the crash report. Confirm that the engine is stopped and its listeners are unregistered before release, then verify that quitting and backgrounding while transcription is active no longer crash.

Written by the indexing model from the issue text.

Assessment

Tech stack
macos, swift
Domain
audio-video-rtc, desktop
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
48/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.