SDL icon indicating copy to clipboard operation
SDL copied to clipboard

CoreAudio CloseAudioDevice race condition....

Open dkulp opened this issue 3 years ago • 3 comments

There is a race condition in CloseAudioDevice with CoreAudio that will occasionally cause a crash.

In close_audio_device, the device->mixer_lock is destroyed prior to calling current_audio.impl.CloseDevice(device). That's likely OK for non-CoreAudio as device->shutdown is set to one first and the device thread is waited on. However, with CoreAudio, the device->thread is null and instead a thread is handled in SDL_coreaudio.

The outputCallback in SDL_coreaudio MAY trigger between when the mixer_lock is destroyed and when this->hidden->shutdown is set to 1 in COREAUDIO_CloseDevice. In that case, SDL_LockMutex(this->mixer_lock) is called which an invalid mixer_lock as it's already destroyed and triggers an invalid access.

dkulp avatar Aug 30 '22 17:08 dkulp

Possible suggestion - in outputCallback check the device to see if IT is shutdown prior to locking the mixer_lock:

SDL_AudioDevice *this = (SDL_AudioDevice *) inUserData;
if (SDL_AtomicGet(&this->shutdown)) {
        return;  /* don't do anything as the device is shutdown */
}
SDL_LockMutex(this->mixer_lock);
...

dkulp avatar Aug 30 '22 17:08 dkulp

Hmm, I thought we fixed this a few versions ago.

I've been thinking of rewriting the CoreAudio code to use SDL's usual audio thread for the heavy lifting, which maybe I'll do for 2.26.0, but otherwise I'll deal with the race condition.

icculus avatar Aug 30 '22 22:08 icculus

I am able to reproduce this consistently. 100% repro.

grimaldini avatar Sep 16 '22 22:09 grimaldini

@icculus, after your changes (https://github.com/libsdl-org/SDL/commit/411582c710097dbc31b7b3e47ab0eb8cc5568b8c), I am now getting a different exception instead, attached screenshot Screen Shot 2022-09-28 at 1 14 21 PM

grimaldini avatar Sep 28 '22 20:09 grimaldini

@icculus, after your changes (411582c), I am now getting a different exception instead, attached screenshot Screen Shot 2022-09-28 at 1 14 21 PM

Can please you create a new ticket so that it doesn't get lost in here?

sezero avatar Sep 30 '22 17:09 sezero

I'll just reopen this to investigate.

icculus avatar Sep 30 '22 17:09 icculus

@grimaldini I just pushed what I think will be a fix for your issue. When you get a moment, can you try the latest in git and see if the problem goes away?

icculus avatar Sep 30 '22 18:09 icculus

(I should say that neither of these issues ever reproduced on my Mac, but...that's how race conditions work.)

icculus avatar Sep 30 '22 18:09 icculus

@icculus, after pulling the latest changes, I now get a different error: Screen Shot 2022-09-30 at 12 24 26 PM

grimaldini avatar Sep 30 '22 19:09 grimaldini

@grimaldini Can you uncheck "C++: on throw" and "C++: on catch" in the "BREAKPOINTS" section at the bottom of the window, and run this again? It might not be crashing, it might be catching that C++ exception internally and moving on normally.

icculus avatar Sep 30 '22 21:09 icculus

@icculus, yes, the issue I reported was an exception not a crash. If I remove that breakpoint, it will continue exiting the app, but I'd like to keep it to catch exceptions elsewhere in the project.

grimaldini avatar Sep 30 '22 21:09 grimaldini

I probably can't control what C++ exceptions Apple's frameworks throw internally, but what's that last line in the terminal say? "no object with g" ... something...?

icculus avatar Sep 30 '22 21:09 icculus

@icculus here's the full console output:

2022-09-30 17:22:46.910344-0700 FW[11954:721902] [plugin] AddInstanceForFactory: No factory registered for id <CFUUID 0x10453ca00> F8BB1C28-BAE8-11D6-9C31-00039315CD46
2022-09-30 17:22:46.916494-0700 FW[11954:721902]  HALC_ProxyObjectMap::_CopyObjectByObjectID: failed to create the local object
2022-09-30 17:22:46.916774-0700 FW[11954:721902]  HALC_ShellDevice::RebuildControlList: couldn't find the control object
2022-09-30 17:22:46.961146-0700 FW[11954:722362] [aqme]        MEMixerChannel.cpp:1636  client <AudioQueueObject@0x104836200; [0]; play> got error 2003332927 while sending format information
2022-09-30 17:22:54.969041-0700 FW[11954:721902] [aqme]        MEMixerChannel.cpp:1636  client <AudioQueueObject@0x104836200; [0]; play> got error 2003332927 while sending format information
2022-09-30 17:22:54.980230-0700 FW[11954:721902]  AudioObjectGetPropertyData: no object with given ID 0

grimaldini avatar Oct 01 '22 00:10 grimaldini

@icculus, These last commits seemed to have fixed the exception, thanks! The output still seems to show some failure at startup but it's not erroring out as an exception

2022-10-19 22:52:47.934446-0700 FW[77336:3349508] [plugin] AddInstanceForFactory: No factory registered for id <CFUUID 0x1046e5190> F8BB1C28-BAE8-11D6-9C31-00039315CD46
2022-10-19 22:52:48.690088-0700 FW[77336:3349800] [aqme]        MEMixerChannel.cpp:1636  client <AudioQueueObject@0x10602de00; [0]; play> got error 2003332927 while sending format information

feel free to close the issue!

grimaldini avatar Oct 20 '22 05:10 grimaldini