SDL icon indicating copy to clipboard operation
SDL copied to clipboard

[MacOS] Crash during debugging pointing to close audio code

Open MrOnlineCoder opened this issue 6 months ago • 4 comments

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)

MrOnlineCoder avatar Jun 06 '25 12:06 MrOnlineCoder

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.

icculus avatar Jun 06 '25 20:06 icculus

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.

MrOnlineCoder avatar Jun 06 '25 22:06 MrOnlineCoder

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.

matthewkayin avatar Jun 08 '25 22:06 matthewkayin

Same issues here. Seems harmless but requires manual intervention to resume debugging execution.

jawaidbazyar2 avatar Jun 15 '25 15:06 jawaidbazyar2

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.

icculus avatar Jul 11 '25 16:07 icculus