2011-10-12 94 views
4

我现在有什么似乎是无法解决的EXC_BAD_ACCESS问题。 我试过启用NSZombie,因为似乎是许多帖子中的建议,但我正在处理c指针而不是obj c对象,所以我没有得到任何有用的调试信息。间歇性extaudiofileread exc_bad_access

我的代码的工作方式是,在它需要事先从磁盘一些音频I分离一个新的POSIX线程的指针传递约我想要的音频信息。然后我读了一些样品。 我在NSThread或NSOperation上选择posix的原因是因为它看起来速度更快。我的音频相当密集,所以我需要尽快读取音频。

我该如何解决这个错误的访问错误?它不会一直发生。有时它似乎在应用程序非常繁忙时发生。偶尔它不会发生。

反正我有可能只是抛出一个尝试捕捉周围这是一个速战速决?我还能如何调查这种情况的原因呢?

编辑这是一个单独的问题,我问一个链接,但它关系到同样的问题

[线程的激烈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 =线程ID;

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's 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); 

}

编辑2

O.K我已经想通了如何使用malloc历史。我有一个很大的跟踪声明。这是我第一次在&之前见过类似的东西,我不知道如何用它来帮助自己。

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 
+0

'似乎执行得更快' - 除非你很快创建线程,我非常怀疑用于创建线程的方法会影响它们的性能。但是,请用一些基准证明我的错误;) – deanWombourne

+0

您认为快速多快?我每秒钟分离16到24个线程。这是否过度? – dubbeat

+0

我认为这有点过分,是的。我会考虑重新思考架构 - 用这么多线程创建线程的成本将超过它们的好处。有什么可以顺序执行的,所以你创建的线程少得多吗? – deanWombourne

回答

1

我最终找到了解决这个问题的办法。每次我需要音频时,我都会创建一个新线程来获取音频。当线程正在为特定的缓冲区获取音频时,相同的缓冲区会再次请求数据,从而导致同时访问相同的缓冲区,即exc_bad_access。

我具有一个线程等待和被发送信号使用POSIX条件获取数据解决了这个。

这里所有的答案都是有用的,帮助我学到了很多关于调试。谢谢你们..

+0

非常好,你有它排序!我一有空,就会看这个。这说我可能不会有太多的帮助,因为我认为这很可能是缓冲区大小计算问题。 –

+0

好消息。我建议你将你的答案标记为已接受,所以它不会出现在没有答案的列表中...... :) –

0

问题几乎肯定会发生,因为你的阅读记忆你不应该。因此EXC_BAD_ACCESS。最重要的是你的缓冲区大小和你正在阅读的内存数量都是正确的。例如,如果您尝试读取超过缓冲区的值,则会收到错误消息。

ExtAudioFileRead,在&readoutpt2值应指定的帧的数量。你确定这个值是正确的吗? bufferList是否足够大以存储该帧数?当你读数据时,你是否前进了一个指针bufferList,并且你提前的数额是否正确?

您是否正确地根据基础类型分配内存?例如你的音频数据是整数还是浮点格式?

基本上,一切都需要添加正确,否则你会吹的地方的缓冲区!其他

一个工具来尝试跟踪内存问题是guard malloc。您可以在这里找到更多信息Enabling the Malloc Debugging Features

+0

是的,我确定readoutpt2的值是correc,我的缓冲区列表也一样。 – dubbeat

+0

样本是什么格式?整数或浮点数?你对缓冲区分配的计算是什么?有多少个频道? –

+0

样本被签名为16位整数,2个音频通道。作为最好的猜测,你会说这个问题与缓冲区列表有关,而不是从磁盘读取的实际音频?如果我同时访问8个音频源,一切正常。不仅如此,我得到的错误。是否有可能是由于缺乏资源代码线程没有充分执行,例如:创建缓冲区 – dubbeat

1

我发现在你的下面几行代码:

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

您malloc'ing的AudioBufferList有一个AudioBuffer的能力,但后来表明它实际上有两个。尝试将该“*(1)”更改为“*(2)”。

除了这个,你不应该执行的malloc的或ExtAudioFileOpen在线程,因为这些会占用时间。如果您可以设法预先执行malloc和ExtAudioFileOpen,并将它们保存在您的文件的结构数组中,您可能会发现性能/稳定性有所提高。

我可能没有阅读的代码完全正确,因为它看起来像格式有一个小搞砸,但我希望这会有所帮助。

1

您可以通过它定位,并找出为什么它是错的,而不是由一个try/catch解决这个问题。

Guard Malloc可以帮助您识别程序中的许多问题。这是一个可以在Xcode中启用的诊断选项。当你试图读或写你不拥有的内存时,该选项的目的是失败,使得程序的哪一部分导致问题比通常更清晰。全部细节:man guardmalloc。第一步是正确所有问题guardmalloc指出。您应该可以在没有这些问题的情况下运行您的应用程序数小时。

如果你想要异常和运行时检查,以帮助您识别早期(这是值得你考虑)这些问题,考虑C++而不是C为您实现。

更新

如果它是一个堆分配是有问题的分配,那么malloc的记录可能会帮助你。当启用malloc日志并且调试器暂停执行时,只需使用malloc_history即可查看用于分配的调用堆栈。 malloc_history将查找日志中的地址并转储alloc创建的调用堆栈。从那里,你只需按照你的程序中的分配流程来找出你的错误。

+0

我无法使用malloc提供的信息。提供的内存地址显示了malloc发生的位置。 (不知道这是否与exc_bad_access相关)。我放入一个中断点并查看调试器中所有对象的内存地址,但我无法找到与错误中地址匹配的对象。 – dubbeat

+0

@dubbeat已更新 – justin

+0

我收到此消息“malloc:使用标准记录器将磁带录制到磁盘。”我在哪里可以查看已录制的内容? – dubbeat