We are currently migrating Bugzilla to GitHub issues.
Any changes made to the bug tracker now will be lost, so please do not post new bugs or make changes to them.
When we're done, all bug URLs will redirect to their equivalent location on the new bug tracker.

Bug 3649

Summary: Audio device leaks memory slowly over time
Product: SDL Reporter: Sean <seant29372>
Component: audioAssignee: Ryan C. Gordon <icculus>
Status: RESOLVED FIXED QA Contact: Sam Lantinga <slouken>
Severity: normal    
Priority: P2    
Version: 2.0.5   
Hardware: x86_64   
OS: Mac OS X 10.10   

Description Sean 2017-05-12 16:03:55 UTC
Creating a bare-bones program that outputs blank sound will slowly cause the memory to increase over time.

Memory consumption is detected via `top`.

I've created a repository on GitHub that demonstrates this issue, here:

https://github.com/voidqk/sdl-audio-leak

The main program is very simple:

```
void sdl_copy_audio(void *userdata, Uint8* stream, int len){
	memset(stream, 0, len);
}

int main(int argc, char **argv){
	SDL_Init(SDL_INIT_AUDIO);
	SDL_AudioSpec want, have;
	SDL_AudioDeviceID dev;
	SDL_memset(&want, 0, sizeof(want));
	want.freq = 48000;
	want.format = AUDIO_F32;
	want.channels = 2;
	want.samples = 2048;
	want.callback = sdl_copy_audio;
	dev = SDL_OpenAudioDevice(NULL, 0, &want, &have, 0);
	if (dev == 0)
		fprintf(stderr, "Failed to open audio: %s\n", SDL_GetError());
	else{
		SDL_PauseAudioDevice(dev, 0); // begin playing
		printf("hit a key to close audio device\n");
		fgetc(stdin);
		SDL_CloseAudioDevice(dev);
	}
	SDL_Quit();
	printf("hit a key to exit\n");
	fgetc(stdin);
	return 0;
}
```

The memory usage reported by `top` over time is:

```
COMMAND                TIME             MEM
sdl-audio-leak         00:00.16         2384K+
sdl-audio-leak         00:02.94         2892K+
sdl-audio-leak         00:06.02         3452K+
sdl-audio-leak         00:09.02         3996K
sdl-audio-leak         00:12.02         4524K+
sdl-audio-leak         00:15.03         5052K+
```
Comment 1 Ryan C. Gordon 2017-05-18 20:51:51 UTC
I can't reproduce this here. My memory usage goes up by a few kilobytes for a few seconds, and then stays stable, not changing over the course of several minutes.

Same result here between the SDL 2.0.5 release and the latest in revision control.

It's possible macOS had a bug fixed since 10.10.5, though...? I'm on 10.12.4.

--ryan.
Comment 2 Sean 2017-05-22 17:36:53 UTC
I've been playing with this...

I believe the leak is inside `audioqueue_thread` in file `SDL_coreaudio.m`, on line 696:

https://github.com/voidqk/sdl-audio-leak/blob/master/src/sdl-2.0.5/src/audio/coreaudio/SDL_coreaudio.m#L696

```
while (!SDL_AtomicGet(&this->hidden->shutdown)) {
    CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0.10, 1);
}
```

If I change the second parameter from `0.10` to `0.01`, then the leak rate is much higher.  Here is a small sample:

```
COMMAND            TIME          MEM
sdl-audio-leak     00:00.34      2452K+
sdl-audio-leak     00:02.99      3208K+
sdl-audio-leak     00:06.06      3796K
```

I'm going to dig through some documentation and Google searches and see if I can figure out what is going on.
Comment 3 Sean 2017-05-22 18:17:11 UTC
In fact, changing the loop to the following actually removes the leak:

```
while (!SDL_AtomicGet(&this->hidden->shutdown)) {
    CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, 1);
    SDL_Delay(20);
}
```

Without the `SDL_Delay`, the thread will consume 100% CPU.

I don't think this is a good fix, especially since I don't understand why `CFRunLoopRunInMode` would be leaking in the first place -- but it does work on my system.
Comment 4 Ryan C. Gordon 2017-05-24 04:42:18 UTC
> Without the `SDL_Delay`, the thread will consume 100% CPU.

This is still baffling to me, because your program doesn't leak memory _or_ consume 100% of the CPU on my machine, even without the SDL_Delay call.

Is it possible it's a CoreAudio plugin you've installed? Some audio device I don't have?

--ryan.
Comment 5 Ryan C. Gordon 2017-06-06 04:31:25 UTC
I'm going to resolve this bug as WORKSFORME for now, but if some more information comes to light about what's going wrong here, definitely feel free to reopen the bug.

--ryan.
Comment 6 Sean 2017-09-25 19:39:02 UTC
I just recently updated to Mac OSX 10.12.6, and the leak isn't present.

So you were correct: the leak seems to be a bug in OSX 10.10.5.

Changing to "FIXED" since the correct solution is to simply update the OS to the latest version.