Objective c 对已发布对象进行调试,NSZombie出现问题

Objective c 对已发布对象进行调试,NSZombie出现问题,objective-c,xcode,debugging,nszombie,Objective C,Xcode,Debugging,Nszombie,编辑:我找到了这次崩溃的原因!bbum指出,缓冲区溢出是造成这种情况的一个非常常见的原因,因此我查看了我仅有的缓冲区类型malloc: closedList = (AINavigationCell **)malloc(baseCells.count * sizeof(AINavigationCell *)); 后来我覆盖了超过数组边界的数据,该边界应该比baseCells.count大得多。谢谢你,嗯 问题: 在NSAutoreleasePool-drain期间,我有一个可复制的EXC\u B

编辑:我找到了这次崩溃的原因!bbum指出,缓冲区溢出是造成这种情况的一个非常常见的原因,因此我查看了我仅有的缓冲区类型malloc:

closedList = (AINavigationCell **)malloc(baseCells.count * sizeof(AINavigationCell *));
后来我覆盖了超过数组边界的数据,该边界应该比
baseCells.count
大得多。谢谢你,嗯

问题:
NSAutoreleasePool
-drain期间,我有一个可复制的
EXC\u BAD\u访问
,这似乎表明我过度释放了一个对象。因此,我启用了NSZombie,但程序不再崩溃。我也不会在控制台上记录任何信息。如果我关闭NSZombie,崩溃就会回来。这是什么意思?我以为僵尸就是用来解决这类问题的。如果NSZombie帮不上忙,有没有其他方法来询问这个过度释放的对象

此外,该崩溃无法在模拟器上复制,这就是为什么我不能将仪器与NSZombie一起使用

以下是崩溃点的回溯

#0  0x31ac8bc8 in _cache_fill ()
#1  0x31acaf8e in lookUpMethod ()
#2  0x31ac8780 in _class_lookupMethodAndLoadCache ()
#3  0x31ac859a in objc_msgSendSuper_uncached ()
#4  0x328014f0 in -[__NSArrayReverseEnumerator dealloc] ()
#5  0x327b1f7a in -[NSObject(NSObject) release] ()
#6  0x327b63c8 in CFRelease ()
#7  0x327b58de in _CFAutoreleasePoolPop ()
#8  0x320e132c in NSPopAutoreleasePool ()
#9  0x30899048 in CAPopAutoreleasePool ()
#10 0x30902784 in CA::Display::DisplayLink::dispatch ()
#11 0x309027ea in CA::Display::IOMFBDisplayLink::callback ()
#12 0x30076bfa in IOMobileFramebufferVsyncNotifyFunc ()
#13 0x333dee6a in IODispatchCalloutFromCFMessage ()
#14 0x327e8be6 in __CFMachPortPerform ()
#15 0x327e06fe in __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ ()
#16 0x327e06c2 in __CFRunLoopDoSource1 ()
#17 0x327d2f7c in __CFRunLoopRun ()
#18 0x327d2c86 in CFRunLoopRunSpecific ()
#19 0x327d2b8e in CFRunLoopRunInMode ()
#20 0x3094a4aa in GSEventRunModal ()
#21 0x3094a556 in GSEventRun ()
#22 0x32c14328 in -[UIApplication _run] ()
#23 0x32c11e92 in UIApplicationMain ()
#24 0x00002556 in main (argc=1, argv=0x2fdff660) at /Users/hyn/Desktop/MyProject-trunk/main.m:14

你所描述的问题可能是以下几点之一:;您可能过度释放了一个对象,或者损坏了内存。如果您损坏了内存,特别是损坏了对象的前几个字节,那么它很容易在自动释放池耗尽(或任何其他消息)期间显示为崩溃

崩溃发生在设备上,而不是模拟器上,这也表明内存损坏。设备[ARM]的体系结构与模拟器[i386]的体系结构大不相同,可能存在许多问题

通常情况下,它的表现并不那么一致

首先,发布崩溃的回溯。这可能会有帮助

其次,您是否执行任何类型的原始
malloc
调用?还是用数据填充缓冲区?此类崩溃的最常见原因是运行超过缓冲区的末尾


(上面的内容是在OP修复了问题之后添加的,但是——对于归档)

该崩溃跟踪是内存损坏的典型特征。也就是说,
isa
指针——指向实例类的对象中第一个指针的字节值——被踩踏。当您在对象之前的分配中溢出内存缓冲区时,通常会发生这种情况。如果只是几个字节的溢出,那么不同平台之间的行为可能会有所不同,因为malloc quanta——分配的实际大小(一个平台上需要90个字节,而另一个平台可能需要96个字节,另一个是128个字节)——在平台之间甚至在发布版本之间都有所不同

特别是,isa被一个看起来很像指针的值踩踏,运行时会取消对垃圾值的引用,然后尝试将结果位置作为类的方法表处理

每当您看到某个
objc_msgSend*()
函数发生几帧深度的崩溃时,很可能是内存损坏,如果是这样,几乎总是缓冲区溢出


因为这很容易做到,所以通过僵尸检测测试仍然是一个好主意,以捕捉“有时它实际上只是一个过度发布的案例”。

您的建议非常正确。我遇到了缓冲区溢出问题。你帮我省了几个小时,可能是几天的调试时间。我一直在努力寻找根本不存在的过度扩张。非常感谢。bbum再次展示了它的非凡之处!:-)优秀的调试信息,特别是关于结果在模拟器和设备上的差异(“duh”,我应该意识到这一点),也许更重要的是,在不同的版本中,我认为这是不可能的。非常感谢你在以后的时间里救了我。在我的情况下,我收到了类似的错误消息。我在ARC上,我如何才能克服释放的对象?@AmoghTalpallikar在发布错误消息和崩溃(以及围绕崩溃的代码)时提出了一个新问题。
#0  0x31ac8bc8 in _cache_fill ()
#1  0x31acaf8e in lookUpMethod ()
#2  0x31ac8780 in _class_lookupMethodAndLoadCache ()
#3  0x31ac859a in objc_msgSendSuper_uncached ()
#4  0x328014f0 in -[__NSArrayReverseEnumerator dealloc] ()