Intermittent extaudiofileread exc_bad_access

I have what at the moment seems like an insoluble EXC_BAD_ACCESS problem. I tried to include NSZombie, it seems, advice in many posts, but I am dealing with c pointers, not obj c objects, so I am not getting any useful debugging information.

The way my code works is that before it needs some audio from the disk, I disconnect the new posix stream, passing it a pointer to information about the desired audio. Then I read a few samples. The reason I chose posix over NSThread or NSOperation is because it seemed to run faster. My sound is pretty intense, so I need to read audio as quickly as possible.

How can I fix this bad access error? This does not happen all the time. Sometimes this happens when the application is very busy. Very rarely, this does not happen at all.

Anyway, could I just give up trying to catch this as a quick fix? How else can I investigate the causes of this?

Change This is a link to a separate question that I asked, but it is related to the same problem.

[Threading for intensely io] [1]

//detachnewthread gets called from remoteio callback void detachnewthread(AudioSourceOBJ str) { //..... code removed for brevity if(str) { int rc; rc = pthread_create(&str->thread, NULL, FetchAudio, (void *)str); if (rc){ printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1); } } } void *FetchAudio(void *threadid) 

{AudioSourceOBJ soundptr = threadid;

 AudioUnitSampleType *outSamplesChannelLeft; AudioUnitSampleType *outSamplesChannelRight; outSamplesChannelLeft = (AudioUnitSampleType *) soundptr->queuebuffer->ABL->mBuffers[0].mData; outSamplesChannelRight = (AudioUnitSampleType *)soundptr->queuebuffer->ABL->mBuffers[0].mData; // ExtAudioFileRef audioFileRef; // result= ExtAudioFileOpenURL(str->path, &str->audioFileObject); AudioStreamBasicDescription importFormat = {0}; size_t bytesPerSample = sizeof (AudioUnitSampleType); // Fill the application audio format struct fields to define a linear PCM, // stereo, noninterleaved stream at the hardware sample rate. importFormat.mFormatID = kAudioFormatLinearPCM; importFormat.mFormatFlags = kAudioFormatFlagsAudioUnitCanonical; importFormat.mBytesPerPacket = bytesPerSample; importFormat.mFramesPerPacket = 1; importFormat.mBytesPerFrame = bytesPerSample; importFormat.mChannelsPerFrame = 2; // 2 indicates stereo importFormat.mBitsPerChannel = 8 * bytesPerSample; importFormat.mSampleRate = 44100; ExtAudioFileSetProperty ( engineDescribtion.audiofilerefs[soundptr->audioindex], kExtAudioFileProperty_ClientDataFormat, sizeof (importFormat), &importFormat ); UInt32 numberofframestoread=(soundptr->amounttoread); AudioBufferList *bufferList; bufferList = (AudioBufferList *) malloc ( sizeof (AudioBufferList) + sizeof (AudioBuffer) * (1) ); // initialize the mNumberBuffers member bufferList->mNumberBuffers = 2; // initialize the mBuffers member to 0 AudioBuffer emptyBuffer = {0}; size_t arrayIndex; for (arrayIndex = 0; arrayIndex < 2; arrayIndex++) { bufferList->mBuffers[arrayIndex] = emptyBuffer; } // set up the AudioBuffer structs in the buffer list bufferList->mBuffers[0].mNumberChannels = 1; bufferList->mBuffers[0].mDataByteSize = numberofframestoread * sizeof (AudioUnitSampleType); bufferList->mBuffers[0].mData = (AudioUnitSampleType*)calloc(numberofframestoread, sizeof(AudioUnitSampleType)); bufferList->mBuffers[1].mNumberChannels = 1; bufferList->mBuffers[1].mDataByteSize = numberofframestoread * sizeof (AudioUnitSampleType); bufferList->mBuffers[1].mData = (AudioUnitSampleType*)calloc(numberofframestoread, sizeof(AudioUnitSampleType)); AudioUnitSampleType *inSamplesChannelLeft=bufferList->mBuffers[0].mData; AudioUnitSampleType *inSamplesChannelRight=bufferList->mBuffers[1].mData; // UInt32 read=(UInt32)soundptr->fetchsample; UInt32 read_plus_half_buffer=soundptr->fetchsample; UInt32 readdestination= read_plus_half_buffer+numberofframestoread; UInt32 actualsamplesread=0; actualsamplesread=numberofframestoread; if (readdestination>soundptr->perfectframecount) { UInt32 readinpt1=0; UInt32 readoutpt1=0; UInt32 readinpt2=0; UInt32 readoutpt2=0; Float32 readtillendamount=0; readinpt1=read_plus_half_buffer; readoutpt1=soundptr->perfectframecount; readinpt2=0; if(read_plus_half_buffer>soundptr->perfectframecount) { readtillendamount=numberofframestoread; readinpt1=read_plus_half_buffer-soundptr->perfectframecount; }else { readtillendamount=soundptr->perfectframecount - readinpt1; readoutpt2=numberofframestoread-readtillendamount; } actualsamplesread= readtillendamount; ExtAudioFileSeek(engineDescribtion.audiofilerefs[soundptr->audioindex], readinpt1); ExtAudioFileRead(engineDescribtion.audiofilerefs[soundptr->audioindex],&actualsamplesread , bufferList); int writeposition=soundptr->queuebuffer->position; for (int i=0; i<actualsamplesread; i++) { outSamplesChannelLeft[writeposition]=inSamplesChannelLeft[i]; outSamplesChannelRight[writeposition]=inSamplesChannelRight[i]; writeposition++; } if (actualsamplesread!=readtillendamount) { UInt32 newzeroamount= readtillendamount-actualsamplesread; for (int j=0; j<newzeroamount; j++) { outSamplesChannelLeft[writeposition]=0; outSamplesChannelRight[writeposition]=0; writeposition++; } } bufferList->mBuffers[1].mDataByteSize = readoutpt2 * sizeof (AudioUnitSampleType); bufferList->mBuffers[0].mDataByteSize = readoutpt2 * sizeof (AudioUnitSampleType); ExtAudioFileSeek(engineDescribtion.audiofilerefs[soundptr->audioindex], 0); ExtAudioFileRead(engineDescribtion.audiofilerefs[soundptr->audioindex],&readoutpt2 , bufferList); for (int k=0; k<readoutpt2; k++) { outSamplesChannelLeft[writeposition]=inSamplesChannelLeft[k]; outSamplesChannelRight[writeposition]=inSamplesChannelRight[k]; writeposition++; } }else if(readdestination<=soundptr->perfectframecount){ ExtAudioFileSeek(engineDescribtion.audiofilerefs[soundptr->audioindex], read_plus_half_buffer); bufferList->mBuffers[1].mDataByteSize = actualsamplesread * sizeof (AudioUnitSampleType); bufferList->mBuffers[0].mDataByteSize = actualsamplesread * sizeof (AudioUnitSampleType); // crash happens here if(bufferList) { assert( ExtAudioFileRead(engineDescribtion.audiofilerefs[soundptr->audioindex],&actualsamplesread , bufferList)); }else { printf("NO BUFFER"); } int writeposition=soundptr->queuebuffer->position; for (int i=0; i<actualsamplesread; i++) { outSamplesChannelLeft[writeposition]=inSamplesChannelLeft[i]; outSamplesChannelRight[writeposition]=inSamplesChannelRight[i]; writeposition++; } if (actualsamplesread!=numberofframestoread) { int zerosamples=0; zerosamples=numberofframestoread-actualsamplesread; for (int j=0; j<zerosamples; j++) { outSamplesChannelLeft[writeposition]=0; outSamplesChannelRight[writeposition]=0; writeposition++; } } }else { printf("unknown condition"); } free(bufferList->mBuffers[0].mData); free(bufferList->mBuffers[1].mData); free(bufferList); bufferList=nil; soundptr->queuebuffer->isreading=NO; // pthread_detach(soundptr->thread); // free(&soundptr->m_lock); return 0; // pthread_exit(NULL); 

}

Edit 2

OK I figured out how to use the malloc story. I have a big trace report. This is the first time I've ever seen something like this before, and I don't know how to use it to help myself.

  ALLOC 0x6c67000-0x6c67fd7 [size=4056]: thread_a019c540 |start | main | UIApplicationMain | GSEventRun | GSEventRunModal | CFRunLoopRunInMode | CFRunLoopRunSpecific | __CFRunLoopRun | __CFRunLoopDoSource1 | __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ | migHelperRecievePortCallout | _XReceivedStatusBarDataAndActions | _UIStatusBarReceivedStatusBarDataAndActions | -[UIStatusBarServer _receivedStatusBarData:actions:] | -[UIStatusBarForegroundView setStatusBarData:actions:animated:] | -[UIStatusBarLayoutManager updateItemsWithData:actions:animated:] | -[UIStatusBarLayoutManager _updateItemView:withData:actions:animated:] | -[UIStatusBarItemView updateContentsAndWidth] | -[UIStatusBarTimeItemView contentsImageForStyle:] | -[UIStatusBarItemView drawText:forStyle:] | -[UIStatusBarItemView drawText:forStyle:forWidth:lineBreakMode:letterSpacing:] | -[NSString(UIStringDrawing) drawAtPoint:forWidth:withFont:lineBreakMode:letterSpacing:] | -[NSString(UIStringDrawing) drawAtPoint:forWidth:withFont:lineBreakMode:letterSpacing:includeEmoji:] | -[NSString(WebStringDrawing) _web_drawAtPoint:forWidth:withFont:ellipsis:letterSpacing:includeEmoji:] | -[NSString(WebStringDrawing) __web_drawAtPoint:forWidth:withFont:ellipsis:letterSpacing:includeEmoji:measureOnly:] | -[NSString(WebStringDrawing) __web_drawAtPoint:forWidth:withFont:ellipsis:letterSpacing:includeEmoji:measureOnly:renderedStringOut:] | drawAtPoint(unsigned short const*, int, WebCore::FloatPoint const&, WebCore::Font const&, WebCore::GraphicsContext*, WebCore::BidiStatus*, int) | WebCore::Font::drawSimpleText(WebCore::GraphicsContext*, WebCore::TextRun const&, WebCore::FloatPoint const&, int, int) const | WebCore::Font::drawGlyphBuffer(WebCore::GraphicsContext*, WebCore::GlyphBuffer const&, WebCore::TextRun const&, WebCore::FloatPoint&) const | WebCore::Font::drawGlyphs(WebCore::GraphicsContext*, WebCore::SimpleFontData const*, WebCore::GlyphBuffer const&, int, int, WebCore::FloatPoint const&, bool) const | WebCore::showGlyphsWithAdvances(WebCore::FontPlatformData const&, CGContext*, unsigned short const*, CGSize const*, unsigned long) | CGContextShowGlyphsWithAdvances | draw_glyphs | ripc_DrawGlyphs | ripc_RenderGlyphs | CGGlyphLockLockGlyphBitmaps | create_missing_bitmaps | CGFontCreateGlyphBitmap8 | aa_create | malloc | malloc_zone_malloc ---- FREE 0x6c67000-0x6c67fd7 [size=4056]: thread_a019c540 |start | main | UIApplicationMain | GSEventRun | GSEventRunModal | CFRunLoopRunInMode | CFRunLoopRunSpecific | __CFRunLoopRun | __CFRunLoopDoSource1 | __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ | migHelperRecievePortCallout | _XReceivedStatusBarDataAndActions | _UIStatusBarReceivedStatusBarDataAndActions | -[UIStatusBarServer _receivedStatusBarData:actions:] | -[UIStatusBarForegroundView setStatusBarData:actions:animated:] | -[UIStatusBarLayoutManager updateItemsWithData:actions:animated:] | -[UIStatusBarLayoutManager _updateItemView:withData:actions:animated:] | -[UIStatusBarItemView updateContentsAndWidth] | -[UIStatusBarTimeItemView contentsImageForStyle:] | -[UIStatusBarItemView drawText:forStyle:] | -[UIStatusBarItemView drawText:forStyle:forWidth:lineBreakMode:letterSpacing:] | -[NSString(UIStringDrawing) drawAtPoint:forWidth:withFont:lineBreakMode:letterSpacing:] | -[NSString(UIStringDrawing) drawAtPoint:forWidth:withFont:lineBreakMode:letterSpacing:includeEmoji:] | -[NSString(WebStringDrawing) _web_drawAtPoint:forWidth:withFont:ellipsis:letterSpacing:includeEmoji:] | -[NSString(WebStringDrawing) __web_drawAtPoint:forWidth:withFont:ellipsis:letterSpacing:includeEmoji:measureOnly:] | -[NSString(WebStringDrawing) __web_drawAtPoint:forWidth:withFont:ellipsis:letterSpacing:includeEmoji:measureOnly:renderedStringOut:] | drawAtPoint(unsigned short const*, int, WebCore::FloatPoint const&, WebCore::Font const&, WebCore::GraphicsContext*, WebCore::BidiStatus*, int) | WebCore::Font::drawSimpleText(WebCore::GraphicsContext*, WebCore::TextRun const&, WebCore::FloatPoint const&, int, int) const | WebCore::Font::drawGlyphBuffer(WebCore::GraphicsContext*, WebCore::GlyphBuffer const&, WebCore::TextRun const&, WebCore::FloatPoint&) const | WebCore::Font::drawGlyphs(WebCore::GraphicsContext*, WebCore::SimpleFontData const*, WebCore::GlyphBuffer const&, int, int, WebCore::FloatPoint const&, bool) const | WebCore::showGlyphsWithAdvances(WebCore::FontPlatformData const&, CGContext*, unsigned short const*, CGSize const*, unsigned long) | CGContextShowGlyphsWithAdvances | draw_glyphs | ripc_DrawGlyphs | ripc_RenderGlyphs | CGGlyphLockLockGlyphBitmaps | create_missing_bitmaps | CGFontCreateGlyphBitmap8 | aa_destroy | free ALLOC 0x6c67000-0x6c67fff [size=4096]: thread_b024f000 |thread_start | _pthread_start | __NSThread__main__ | -[NSThread main] | -[FirstViewController checkstate:] | CALayer_setter_kCAValueFloat | CALayer_setter | CA::Transaction::ensure_compat() | CA::Transaction::create() | malloc | malloc_zone_malloc ---- FREE 0x6c67000-0x6c67fff [size=4096]: thread_b024f000 |thread_start | _pthread_start | __NSThread__main__ | -[NSString compare:options:] | _pthread_exit | _pthread_tsd_cleanup | free ALLOC 0x6c67000-0x6c67fff [size=4096]: thread_b0353000 |thread_start | _pthread_start | __NSThread__main__ | -[NSThread main] | -[FirstViewController checkstate:] | CALayer_setter_kCAValueFloat | CALayer_setter | CA::Transaction::ensure_compat() | CA::Transaction::create() | malloc | malloc_zone_malloc ---- FREE 0x6c67000-0x6c67fff [size=4096]: thread_b0353000 |thread_start | _pthread_start | __NSThread__main__ | -[NSString compare:options:] | _pthread_exit | _pthread_tsd_cleanup | free ALLOC 0x6c67000-0x6c67fff [size=4096]: thread_b0763000 |thread_start | _pthread_start | FetchAudio | ExtAudioFileRead | ExtAudioFile::Read(unsigned long, unsigned long&, AudioBufferList*) | AudioConverterFillComplexBuffer | BufferedAudioConverter::FillBuffer(unsigned long&, AudioBufferList&, AudioStreamPacketDescription*) | AudioConverterChain::RenderOutput(CABufferList*, unsigned long, unsigned long&, AudioStreamPacketDescription*) | BufferedAudioConverter::FillBuffer(unsigned long&, AudioBufferList&, AudioStreamPacketDescription*) | CBRConverter::RenderOutput(CABufferList*, unsigned long, unsigned long&, AudioStreamPacketDescription*) | BufferedAudioConverter::GetInputBytes(unsigned long, unsigned long&, CABufferList const*&) | CABufferList::AllocateBuffers(unsigned long) | operator new[](unsigned long) | operator new(unsigned long) | malloc | malloc_zone_malloc ---- FREE 0x6c67000-0x6c67fff [size=4096]: thread_b0763000 |thread_start | _pthread_start | FetchAudio | ExtAudioFileRead | ExtAudioFile::Read(unsigned long, unsigned long&, AudioBufferList*) | AudioConverterFillComplexBuffer | BufferedAudioConverter::FillBuffer(unsigned long&, AudioBufferList&, AudioStreamPacketDescription*) | AudioConverterChain::RenderOutput(CABufferList*, unsigned long, unsigned long&, AudioStreamPacketDescription*) | BufferedAudioConverter::FillBuffer(unsigned long&, AudioBufferList&, AudioStreamPacketDescription*) | CBRConverter::RenderOutput(CABufferList*, unsigned long, unsigned long&, AudioStreamPacketDescription*) | BufferedAudioConverter::GetInputBytes(unsigned long, unsigned long&, CABufferList const*&) | free ALLOC 0x6c67000-0x6c67fff [size=4096]: thread_b0a6f000 |thread_start | _pthread_start | FetchAudio | ExtAudioFileRead | ExtAudioFile::Read(unsigned long, unsigned long&, AudioBufferList*) | AudioConverterFillComplexBuffer | BufferedAudioConverter::FillBuffer(unsigned long&, AudioBufferList&, AudioStreamPacketDescription*) | AudioConverterChain::RenderOutput(CABufferList*, unsigned long, unsigned long&, AudioStreamPacketDescription*) | BufferedAudioConverter::FillBuffer(unsigned long&, AudioBufferList&, AudioStreamPacketDescription*) | CBRConverter::RenderOutput(CABufferList*, unsigned long, unsigned long&, AudioStreamPacketDescription*) | BufferedAudioConverter::GetInputBytes(unsigned long, unsigned long&, CABufferList const*&) | CABufferList::AllocateBuffers(unsigned long) | operator new[](unsigned long) | operator new(unsigned long) | malloc | malloc_zone_malloc ---- FREE 0x6c67000-0x6c67fff [size=4096]: thread_b0a6f000 |thread_start | _pthread_start | FetchAudio | ExtAudioFileRead | ExtAudioFile::Read(unsigned long, unsigned long&, AudioBufferList*) | AudioConverterFillComplexBuffer | BufferedAudioConverter::FillBuffer(unsigned long&, AudioBufferList&, AudioStreamPacketDescription*) | AudioConverterChain::RenderOutput(CABufferList*, unsigned long, unsigned long&, AudioStreamPacketDescription*) | BufferedAudioConverter::FillBuffer(unsigned long&, AudioBufferList&, AudioStreamPacketDescription*) | CBRConverter::RenderOutput(CABufferList*, unsigned long, unsigned long&, AudioStreamPacketDescription*) | BufferedAudioConverter::GetInputBytes(unsigned long, unsigned long&, CABufferList const*&) | free ALLOC 0x6c67000-0x6c67fff [size=4096]: thread_b0081000 |thread_start | _pthread_start | __NSThread__main__ | -[NSThread main] | -[FirstViewController checkstate:] | CALayer_setter_kCAValueFloat | CALayer_setter | CA::Transaction::ensure_compat() | CA::Transaction::create() | malloc | malloc_zone_malloc ---- FREE 0x6c67000-0x6c67fff [size=4096]: thread_b0081000 |thread_start | _pthread_start | __NSThread__main__ | -[NSString compare:options:] | _pthread_exit | _pthread_tsd_cleanup | free 
+4
source share
4 answers

In the end, I found a solution to this problem. Every time I needed a sound, I created a new stream to extract the sound. At that time, when the stream was extracting sound for a specific buffer, the same buffer requested the data again, as a result of which the same buffer could be obtained simultaneously, thus exc_bad_access.

I solved this by having only one thread waiting and receiving a signal to receive data using the posix condition.

All of the answers here were helpful and helped me learn a lot about debugging. Thanks guys..

+1
source

I noticed the following lines in your code:

 bufferList = (AudioBufferList *) malloc ( sizeof (AudioBufferList) + sizeof (AudioBuffer) * (1) ); // initialize the mNumberBuffers member bufferList->mNumberBuffers = 2; 

You want the AudioBufferList to have the capacity of one AudioBuffer, but then indicate that it actually has two. Try changing "* (1)" to "* (2)".

In addition to this, you should not execute malloc or ExtAudioFileOpen in the stream, as this will take some time. If you manage to pre-execute malloc and ExtAudioFileOpen and just save them in a struct array for your files, you can find performance / stability improvements.

I may not have read the code completely correctly, as the formatting seems to have messed up a bit, but I hope this helps.

+1
source

You fix this by posting it and finding out why it is wrong, and not with try / catch.

Guard Malloc can help you identify many problems in your program. This is a diagnostic parameter that can be enabled in Xcode. The purpose of this option is to crash when trying to read or write memory that you don’t have, which makes it more clear than usual which part of your program is causing problems. full details: man guardmalloc . The first step is to fix all the problems that guardmalloc points to. You will not be able to run your application for hours without these problems.

If you need exceptions and runtime checks to help you identify these issues earlier (which is worth your consideration), consider C ++ rather than C for your implementations.

Update

if this is a heap distribution, which is an appropriate allocation, then malloc logging will probably help you. when malloc logging is enabled and the debugger pauses execution, simply use malloc_history to view the column to highlight. malloc_history will look up the address in the log and unload the callstack creating the alloc. from there you simply follow the distribution flow through your program to find what you are wrong.

+1
source

The problem is almost certainly due to the fact that you are reading memory, which should not be. Therefore, EXC_BAD_ACCESS . The important thing is that the size of your buffers and the amount of memory you are reading are correct. For example, if you try to read more than the cost of the buffer, you will receive an error message.

In ExtAudioFileRead value in &readoutpt2 should indicate the number of frames. Are you sure this value is correct? Is bufferList large enough to store this number of frames? Do you bufferList pointer through bufferList as you read the data, and does the correct value fit you?

Are you allocating memory correctly based on the base type? For example, your integer number of audio data or floating point format?

In principle, everything should add up correctly, otherwise you will wake up buffers somewhere!

Another tool for troubleshooting memory issues is guard malloc . You can find more information here Enabling Malloc Debugging Features

0
source

All Articles