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