Re: Guardmalloc breaks after AudioQueueDispose
Re: Guardmalloc breaks after AudioQueueDispose
- Subject: Re: Guardmalloc breaks after AudioQueueDispose
- From: Bankim Bhavsar <email@hidden>
- Date: Mon, 28 Mar 2011 10:53:08 -0700
We are sometimes hitting a double free while calling
AudioQueueDispose(queue, true).
This is more likely when short sounds are played continuously.
Mac OS 10.6.7
Here is pseudo-code of the application
1.) Create output audio queue on main thread and let the callbacks be
invoked on audio queue's internal thread.
AudioQueueNewOutput(
&format,
SoundAQOutputCB, // Callback
stream, // Client data
NULL, // Use CoreAudio's internal thread
kCFRunLoopCommonModes,
0,
&stream->audioQueue);
2.) Stop the output audio queue asynchronously.
AudioQueueStop(stream->audioQueue,
false); // asynchronous stop
3.) Since we are playing short sounds and another stream has to be
started we reset the audio queue and wait for the audio queue
to stop. However we can't wait for as long as 1 sec as seen in the
sample code. We currently max out at 200 milliseconds.
AudioQueueReset(stream->audioQueue);
Poll for 200 msecs max (by sleep()'ing for 20 msecs) and wait for
the audio queue to stop using kAudioQueueProperty_IsRunning property.
AudioQueueGetProperty(
stream->audioQueue,
kAudioQueueProperty_IsRunning,
&isRunning,
&size);
Dispose queue synchronously
AudioQueueDispose(stream->audioQueue, true);
Sometimes after 35-80 successful attempts, we hit a double free in
Audio Queue code:
Thread 5 Crashed:
0 libSystem.B.dylib 0x00007fff800a8e4e __semwait_signal_nocancel + 10
1 libSystem.B.dylib 0x00007fff800a8d50 nanosleep$NOCANCEL + 129
2 libSystem.B.dylib 0x00007fff801056a2 usleep$NOCANCEL + 57
3 libSystem.B.dylib 0x00007fff80124c75 __abort + 113
4 libSystem.B.dylib 0x00007fff80124cd9 abort_report_np + 0
5 libSystem.B.dylib 0x00007fff8003c6f5 free + 128
6 ....audio.toolbox.AudioToolbox 0x00007fff80bfd7c4
AQNodeAllocator::~AQNodeAllocator() + 50
7 ....audio.toolbox.AudioToolbox 0x00007fff80bfeb59
AudioQueueObject::WorkQueue::~WorkQueue() + 49
8 ....audio.toolbox.AudioToolbox 0x00007fff80bfa494
AudioQueueObject::~AudioQueueObject() + 780
9 ....audio.toolbox.AudioToolbox 0x00007fff80c12198 AQServer_DisposeQueue + 63
10 ....audio.toolbox.AudioToolbox 0x00007fff80c1556e AudioQueueDispose + 132
Help will be appreciated in this regard.
Thanks,
Bankim.
On Sun, Mar 27, 2011 at 3:44 PM, Bankim Bhavsar
<email@hidden> wrote:
> Hi Greg,
>
> Did you ever get a response to this question? Did you file a bug with
> Apple regarding this issue?
>
> I'm facing a similar situation wherein playing small sounds repeatedly
> (after about 35 or 80 times)
> sometimes causes AudioQueueDispose(queue, true) to double free a pointer
> in AQNodeAllocator::~AQNodeAllocator().
>
> Thread 5 Crashed:
> 0 libSystem.B.dylib 0x00007fff800a8e4e __semwait_signal_nocancel + 10
> 1 libSystem.B.dylib 0x00007fff800a8d50 nanosleep$NOCANCEL + 129
> 2 libSystem.B.dylib 0x00007fff801056a2 usleep$NOCANCEL + 57
> 3 libSystem.B.dylib 0x00007fff80124c75 __abort + 113
> 4 libSystem.B.dylib 0x00007fff80124cd9 abort_report_np + 0
> 5 libSystem.B.dylib 0x00007fff8003c6f5 free + 128
> 6 ....audio.toolbox.AudioToolbox 0x00007fff80bfd7c4
> AQNodeAllocator::~AQNodeAllocator() + 50
> 7 ....audio.toolbox.AudioToolbox 0x00007fff80bfeb59
> AudioQueueObject::WorkQueue::~WorkQueue() + 49
> 8 ....audio.toolbox.AudioToolbox 0x00007fff80bfa494
> AudioQueueObject::~AudioQueueObject() + 780
> 9 ....audio.toolbox.AudioToolbox 0x00007fff80c12198 AQServer_DisposeQueue + 63
> 10 ....audio.toolbox.AudioToolbox 0x00007fff80c1556e AudioQueueDispose + 132
>
> I'll try enabling guard malloc next...
>
> Thanks,
> Bankim.
>
> On Mon, Dec 8, 2008 at 9:06 AM, Greg Wilson <email@hidden> wrote:
>> I've been trying to convert the simple sound play routines in my app to use
>> the AudioQueue routines. I play either very short sounds or loop some longer
>> ones (and both types can be playing at once). Following the
>> aqplay/AudioQueueTest example, I got my sounds to play but eventually my
>> program crashes, sometimes after playing 20+ sounds successfully.
>>
>> After much headbanging I went back to the example code (aqplay from
>> Developer/Examples/Core Audio/SimpleSDK/AudioQueueTools)) and altered it to
>> play the same sound a number of times. Basically, when GuardMalloc is
>> enabled, the program gets a EXC_BAD_ACCESS in a different thread than my
>> program loop in a routine OSAtomicOr32Barrier called by AQConverterManager
>> when attempting to play the sound the second time.
>>
>> If GuardMalloc is not enabled, things can go to go normally for a while,
>> sometimes even playing 20+ sounds successfully. However, it will usually
>> crashes after playing the sound a number of times. Occasionally I get a note
>> to set a breakpoint in malloc_error_break. When set, the debugger breaks
>> during a calls to either AudioQueueDispose or to AduioQueueStart.
>>
>>
>> (here's what I did to alter the aqplay program. It doesn't require much to
>> alter the program to play sounds one after the other. Basically, I created a
>> routine (playFile )and moved the AudioQueue functions which played the file
>> into this routine from the main routine
>>
>> void playFile (const char *fpath, Float32 volume )
>>
>> {
>> //copy everything from here
>> printf ("Playing file: %s\n", fpath);
>>
>> try {
>> AQTestInfo myInfo;
>>
>> ... etc
>> // down to here
>> catch (CAXException e) {
>> char buf[256];
>> fprintf(stderr, "Error: %s (%s)\n", e.mOperation,
>> e.FormatError(buf));
>> }
>>
>> }
>>
>> then this code was replaced in the main routine to call it repeatedly:
>>
>> int main (int argc, const char * argv[])
>> {
>> const char *fpath = NULL;
>> Float32 volume = 1;
>>
>> for (int i = 1; i < argc; ++i) {
>> const char *arg = argv[i];
>> if (arg[0] != '-') {
>> if (fpath != NULL) {
>> fprintf(stderr, "may only specify one file to
>> play\n");
>> usage();
>> }
>> fpath = arg;
>> } else {
>> arg += 1;
>> if (arg[0] == 'v' || !strcmp(arg, "-volume")) {
>> if (++i == argc)
>> MissingArgument();
>> arg = argv[i];
>> sscanf(arg, "%f", &volume);
>> } else if (arg[0] == 'h' || !strcmp(arg, "-help")) {
>> usage();
>> } else {
>> fprintf(stderr, "unknown argument: %s\n\n",
>> arg - 1);
>> usage();
>> }
>> }
>> }
>>
>> if (fpath == NULL)
>> usage();
>>
>> // these few lines replace the code moved to playfile, and play the
>> same sound file over and over
>> for (int j = 1; j< 200; ++j)
>> playFile(fpath, volume);
>>
>>
>> return 0;
>> }
>>
>> I put Submarine.aiff from System/Library/Sounds into the build directory and
>> added Submarine.aiff as an argument to the active executable.
>>
>> I later changed the lines
>> CFRunLoopRunInMode(kCFRunLoopDefaultMode, 1, false);
>> XThrowIfError(AudioQueueDispose(myInfo.mQueue, true),
>> "AudioQueueDispose(true) failed");
>> XThrowIfError(AudioFileClose(myInfo.mAudioFile),
>> "AudioQueueDispose(false) failed");
>> delete [] myInfo.mPacketDescs;
>>
>> to
>> do {
>> CFRunLoopRunInMode(kCFRunLoopDefaultMode, 5, false);
>> } while (gIsRunning);
>>
>> XThrowIfError(AudioQueueDispose(myInfo.mQueue, true),
>> "AudioQueueDispose(true) failed");
>> XThrowIfError(AudioFileClose(myInfo.mAudioFile),
>> "AudioQueueDispose(false) failed");
>> delete [] myInfo.mPacketDescs;
>> gIsRunning = 1;
>>
>> and set the gIsRunningFlag to 1 when it was defined, ie
>> static UInt32 gIsRunning = 1;
>>
>> (The program sets this to 0 when the queue calls it's listener proc,
>> although it didn't use it )
>>
>> This serves to ensure AudioStopQueue has really stopped the queue and it
>> even gives it an extra bit of time to finish anything it might be doing.
>> However, that didn't change anything. With GuardMalloc enabled, the program
>> still broke during the second attempt at playing the sound (and after about
>> 12 successful plays with GuardMalloc off)
>>
>> Can anyone help me? I've replicated this on a PPC G5, an original intel iMac
>> and a intel macbook all running 10.5.5 using xcode 3.1.1.
>>
>>
>> _______________________________________________
>> Do not post admin requests to the list. They will be ignored.
>> Coreaudio-api mailing list (email@hidden)
>> Help/Unsubscribe/Update your Subscription:
>>
>> This email sent to email@hidden
>>
>
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Coreaudio-api mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden