SDL
SDL copied to clipboard
[MacOS] Crash during debugging pointing to close audio code
This is very obscure and weird bug, therefore I am sorry I may not be able to provide full context needed to resolve it.
Almost every project with SDL3 + SDL_ttf + SDL_mixer + SDL_image crashes when debugged on MacOS, pointing to some code related to audio device closing (although call stack contains SDL_mixer too, it eventually points to SDL3 Audio API).
The code I use is basically pretty straightforward (error checking for all init and create calls is omitted, but it's present and I don't get any errors):
#include <SDL3/SDL.h>
#include <SDL3_image/SDL_image.h>
#include <SDL3_mixer/SDL_mixer.h>
#include <SDL3_ttf/SDL_ttf.h>
int main()
{
SDL_Init(
SDL_INIT_VIDEO | SDL_INIT_AUDIO | SDL_INIT_GAMEPAD);
Mix_Init(MIX_INIT_OGG | MIX_INIT_MP3);
SDL_AudioSpec audioSpec;
audioSpec.channels = MIX_DEFAULT_CHANNELS;
audioSpec.format = MIX_DEFAULT_FORMAT;
audioSpec.freq = MIX_DEFAULT_FREQUENCY;
Mix_OpenAudio(
0, &audioSpec);
TTF_Init();
SDL_Window *window = SDL_CreateWindow(
"App",
1280,
720, 0);
SDL_Renderer *renderer = SDL_CreateRenderer(
window,
NULL);
SDL_Event event;
// create instances of textures, TTF_Fonts, etc...
bool running = true;
while (running)
{
while (SDL_PollEvent(&event))
{
if (event.type == SDL_EVENT_QUIT)
{
running = false;
break;
}
// other event processing
}
// update logic
SDL_RenderClear(renderer);
// my rendering code
SDL_RenderPresent(renderer);
SDL_Delay(16);
}
// Free resources like textures, fonts, etc...
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
Mix_HaltMusic();
Mix_CloseAudio();
Mix_Quit();
TTF_Quit();
SDL_Quit();
return 0;
}
The application runs well, but when I close it, I get a crash witht the following call stack on main thread:
__ulock_wait (@__ulock_wait:5)
_pthread_join (@_pthread_join:155)
SDL_SYS_WaitThread (/home/mronlinecoder/project/build/_deps/sdl3-src/src/thread/pthread/SDL_systhread.c:287)
SDL_WaitThread_REAL (/home/mronlinecoder/project/build/_deps/sdl3-src/src/thread/SDL_thread.c:466)
COREAUDIO_CloseDevice (/home/mronlinecoder/project/build/_deps/sdl3-src/src/audio/coreaudio/SDL_coreaudio.m:638)
ClosePhysicalAudioDevice (/home/mronlinecoder/project/build/_deps/sdl3-src/src/audio/SDL_audio.c:1596)
SDL_CloseAudioDevice_REAL (/home/mronlinecoder/project/build/_deps/sdl3-src/src/audio/SDL_audio.c:1629)
SDL_CloseAudioDevice (/home/mronlinecoder/project/build/_deps/sdl3-src/src/dynapi/SDL_dynapi_procs.h:102)
Mix_CloseAudio (/home/mronlinecoder/project/build/_deps/sdl3_mixer-src/src/mixer.c:1387)
main (/home/mronlinecoder/project/src/Main.cpp:68)
start (@start:622)
There is also an exception on system thread:
__cxa_throw (@__cxa_throw:3)
QueueAccessor::QueueAccessor(unsigned int, audit_token_t const*, bool) (@QueueAccessor::QueueAccessor(unsigned int, audit_token_t const*, bool):73)
AudioQueueInternalStop_Sync(unsigned int) (@AudioQueueInternalStop_Sync(unsigned int):13)
_dispatch_client_callout (@_dispatch_client_callout:8)
_dispatch_root_queue_drain (@_dispatch_root_queue_drain:219)
_dispatch_worker_thread2 (@_dispatch_worker_thread2:42)
_pthread_wqthread (@_pthread_wqthread:60)
When not debugged however, it seems to exit gracefully with 0 exit code.
Used platform and toolchain:
MacOS 14.6.1 (23G93) Darwin Kernel Version 23.6.0
Apple clang version 15.0.0 (clang-1500.3.9.4) Target: arm64-apple-darwin23.6.0 Thread model: posix InstalledDir: /Library/Developer/CommandLineTools/usr/bin
SDL: release-3.2.12 SDL_mixer: main branch latest commit (via FetchContent) SDL_image: main branch latest commit (via FetchContent)
Debugger used: lldb-1500.0.404.7 (launched via VSCode)
I'll try to reproduce this here.
For the second exception: CoreAudio tends to throw exceptions internally that it then catches itself, and Apple's debugger stops on these, but often they are harmless.
For the second exception: CoreAudio tends to throw exceptions internally that it then catches itself, and Apple's debugger stops on these, but often they are harmless.
This is interesting and valuable. Although as I understand, the Mix_CloseAudio triggers a wait or close on CoreAudio thread which gives an exception, but it happens very constintently every time, which is weird and just annoying. I don't know if I can safely add that to ignore list or it's really some problem. Probably the first, as no visible interruptions or problems occur during runtime until the app is closed.
The info about the CoreAudio exceptions is good to know.
I've been having this same AudioQueueInternalStop_Sync crash on MacOS, clang 15, target arm64-apple-darwin23.5.0, SDL 3.2.12, not using SDL_mixer, just SDL3 audio. Happens only when debugging with lldb. If I debug with cppdbg, then the exception isn't caught.
I think I will consider these exceptions harmless for now.
Same issues here. Seems harmless but requires manual intervention to resume debugging execution.
Fwiw, I get CoreAudio debug logging from this test program when run under lldb, but the debugger doesn't halt. Not sure if this changed in a later Xcode or macOS release, or if something else is different.
2025-07-11 11:57:17.605733-0400 test[20678:53302325] [plugin] AddInstanceForFactory: No factory registered for id <CFUUID 0x6000033723a0> F8BB1C28-BAE8-11D6-9C31-00039315CD46
2025-07-11 11:57:17.686501-0400 test[20678:53302325] HALDefaultDevice.cpp:742 Could not find default device for dIn
2025-07-11 11:57:20.419983-0400 test[20678:53302550] [AMCP] 68871 HALC_ProxyIOContext.cpp:1621 HALC_ProxyIOContext::IOWorkLoop: skipping cycle due to overload
2025-07-11 11:57:20.465678-0400 test[20678:53302550] [AMCP] 68871 HALC_ProxyIOContext.cpp:1621 HALC_ProxyIOContext::IOWorkLoop: skipping cycle due to overload
2025-07-11 11:57:20.617129-0400 test[20678:53302550] [AMCP] 68871 HALC_ProxyIOContext.cpp:1621 HALC_ProxyIOContext::IOWorkLoop: skipping cycle due to overload
2025-07-11 11:57:25.033405-0400 test[20678:53302540] [aqsrv] AQ_Server_Common.h:48 Exception caught in AudioQueueInternalStop_Sync - error -66671
(including that "Exception caught" line.)
At any rate, this isn't a bug in SDL, as far as I can tell, so I'm closing for now.