Crash in mixerSuspend

We encountered an Android ARM64 crash inside the FMOD mixer thread while calling System::mixerSuspend(). The complete FMOD logging-library output is available and will be attached.

Environment:

  • FMOD Engine: 2.03.14
  • FMOD library: libfmodL.so, ARM64
  • Device: Samsung SM-A715F
  • OS: Android 12 / SDK 31
  • Application build: 26.5.0.42912
  • FMOD output: AAudio
  • Output configuration: default output, 48 kHz, stereo
  • Local libfmodL.so build ID: 7f6812d87ea9d1a9ea3369c789434094

Crash summary:

Thread: FMOD mixer thre
Signal: 11 (Segmentation fault)
Fault address: 0x0000000000000000

0 libc.so sem_post
1 libfmodL.so 0x140f90
2 libfmodL.so 0x140f90
3 libfmodL.so 0x1381a8
4 libfmodL.so 0x1409d8
5 libc.so
6 libc.so

The crash happened during:

DeviceManagerPollEvents
→ Pause
→ FMODAudioManager
→ FMOD_System_MixerSuspend

Relevant sequence from the log:

  1. FMOD successfully initialized with AAudio:

20:56:06.615
FMOD output after initialization:
type=AAudio (18), drivers=4, selected driver=0 ‘(Default Output)’,
rate=48000 Hz, speaker mode=3, channels=2

  1. The application completed two earlier mixer suspend/resume cycles successfully. Each cycle logged:

FMOD mixer suspend requested
SystemI::mixerSuspend: Suspending output.
Thread::callback: FMOD mixer thread finished.
FMOD mixer suspend completed

FMOD mixer resume requested
Thread::initThread: Init FMOD mixer thread.
FMOD mixer resume completed

  1. Microphone capture was subsequently opened:

20:56:54.272
MicrophoneController: Starting audio capture at 44100 Hz

20:56:54.548
AudioManager: Opened audio capture device with sample rate 44100,
frames 2048, channels 1.

  1. Approximately one minute later, while the application was active and not paused, FMOD failed to stop an AAudio stream:

20:57:53.727
fmod_output_aaudio.cpp:201 AAudio_StopStreamBlocking
Failed to stop stream after 1000ms. State = 13. Result = -885.

20:57:53.728
fmod_output_aaudio.cpp:1010 AAudio_Stop
Cannot stop stream. Result = 0xFFFFFC8B.

At this point the diagnostic context reported:

Paused:false
StackInfo:/Update/GameAudioManager

We understand state 13 to be AAUDIO_STREAM_STATE_DISCONNECTED and result -885 to be AAUDIO_ERROR_TIMEOUT.

  1. FMOD then automatically reconstructed the output:

20:57:54.202
AAudio_CreateOutputStream:
Could not set driver at index [0]. Defaulting to driver with id: 3.

20:57:54.202
AAudio_Init:
Sample rate: HW = 48000, SW = 24000
Block size: HW = 192, SW = 512.

20:57:54.207
Thread::initThread:
Init FMOD mixer thread. Semaphore: Yes, Looping: Yes.

20:57:54.209
Thread::callback:
FMOD mixer thread finished.

Before this reinitialization, the hardware block size was 96 rather than 192.

  1. About five seconds later, the application was paused because the user started an Android in-app purchase:

20:57:58.934
StartBuying(com.outfit7.xxx.soc_bundle)

20:57:58.954
Extern call: Pause

The application first closed its microphone capture device and then suspended FMOD:

20:57:58.968
MicrophoneController: Stopping audio capture

20:57:58.968
AudioManager: Closing audio capture device

20:57:59.043
FMOD pause callback: initialized=1, mixer suspended=0

20:57:59.044
FMOD mixer suspend requested: suspended before=0

20:57:59.044
SystemI::mixerSuspend:
Suspending output.

20:57:59.046
Thread::callback:
FMOD mixer thread finished.

20:57:59.055
CRASH: FMOD mixer thread, SIGSEGV, fault address 0x0

The FMOD mixer suspend completed message was never reached.

We inspected the bundled ARM64 binary around the crash offsets. The sequence corresponding to the stack is:

0x1381a0 Load a semaphore pointer from the FMOD thread object
0x1381a4 Call FMOD’s semaphore-post wrapper
0x140f8c Call libc sem_post
0x140f90 Return address reported in the crash
0x1381a8 Caller return address reported in the crash
0x1409d8 FMOD OS thread trampoline after the thread callback

This appears to indicate that the mixer thread logged that it had finished and then attempted to post a null or already-cleared internal completion semaphore.

Integration details:

  • mixerSuspend() and mixerResume() are called from the same main/lifecycle thread.
  • Duplicate suspend/resume requests are guarded.
  • FMOD Studio updates are skipped while the mixer is suspended.
  • During the fatal transition, an asynchronous UI sound load completed before the pause handler called mixerSuspend().
  • We do not see another project-initiated FMOD API call after the final mixerSuspend() begins.
  • Earlier suspend/resume cycles in the same session completed successfully.
  • The crash only occurred after the AAudio stop timeout and automatic output/mixer-thread reconstruction.