Skip to content

Fix RTCAudioDeviceModule crash during deallocation by making C++ observer teardown thread-safe#74

Merged
ipavlidakis merged 3 commits intodevelopfrom
iliaspavlidakis/fix-rtcaudiodevicemodule-reacey-teardown
Feb 26, 2026
Merged

Fix RTCAudioDeviceModule crash during deallocation by making C++ observer teardown thread-safe#74
ipavlidakis merged 3 commits intodevelopfrom
iliaspavlidakis/fix-rtcaudiodevicemodule-reacey-teardown

Conversation

@ipavlidakis
Copy link
Copy Markdown
Contributor

@ipavlidakis ipavlidakis commented Feb 16, 2026

Description

This change addresses a crash path where AudioDeviceModule.__ivar_destroyer() could crash during app UI teardown / call end because Objective-C++ ivar destruction races with audio-engine lifecycle/worker thread callbacks.

Problem

Crash signature: EXC_BAD_ACCESS in object_cxxDestruct after AudioDeviceModule dealloc.
Triggered during call teardown, while callbacks/release chain from Swift (Call/WebRTCCoordinator) was unwinding.

Root cause

RTCAudioDeviceModule destructor currently removed observer/native linkage and deleted the C++ observer without fully validating thread/teardown state.
If worker thread is gone or quitting, callback paths and object state can become inconsistent.

Fix

In RTCAudioDeviceModule.mm (dealloc), deallocation now:
snapshots native/thread/observer pointers first,
performs detach (SetObserver(nullptr) and observer->delegate_ = nil) only when safe on a non-quitting worker thread,
only then deletes observer state.
avoids unsafe destruction assumptions when thread is unavailable.

Validation

fastlane build command above completes successfully end-to-end.

Notes

No integration-side API changes required.
If consumers perform custom ADM lifecycle mutation, prefer serializing module replacement only after full stop/shutdown flow.

…ardown races

When `RTCAudioDeviceModule` is deallocated, its C++ observer/native state can be
torn down while audio callbacks or thread shutdown are still in progress, which can
lead to `EXC_BAD_ACCESS` during `object_cxxDestruct` in Swift ARC teardown paths.

This change makes deallocation safer by:
- Capturing `_native`, `_workerThread`, and `_observer` locally before teardown.
- Guarding worker-thread teardown work behind `native && workerThread && !IsQuitting()`.
- Detaching observer on the worker thread before deleting it.
- Avoiding unsafe assumptions about worker-thread availability during object destruction.

Build verification:
- Ran: `bundle exec fastlane ios build verbose:true zip_product_skip:true root:/Users/ipavlidakis/workspace/webrtc/src skip_licenses:true maccatalyst_support:false`
- Result: success
@ipavlidakis ipavlidakis self-assigned this Feb 16, 2026
@ipavlidakis ipavlidakis added the bug Something isn't working label Feb 16, 2026
@ipavlidakis ipavlidakis changed the base branch from main to develop February 16, 2026 12:54
@ipavlidakis ipavlidakis merged commit 65b2452 into develop Feb 26, 2026
@ipavlidakis ipavlidakis deleted the iliaspavlidakis/fix-rtcaudiodevicemodule-reacey-teardown branch February 26, 2026 20:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants