2011-01-31 63 views
4

编辑:我发现了这次崩溃的原因! bbum指出,缓冲区溢出是这是一个非常常见的原因,所以我看着唯一的缓冲型的malloc我:调试过度释放的对象,与NSZombie问题

closedList = (AINavigationCell **)malloc(baseCells.count * sizeof(AINavigationCell *)); 

我后来改写过去的数组的边界,这应该是大于多少数据baseCells.count。谢谢你!

问题: 我有一个reproduceable EXC_BAD_ACCESS期间NSAutoreleasePool - 漏,这似乎表明,我是在释放的对象。所以我启用了NSZombie,但程序不再崩溃。我也没有获得任何记录到控制台的信息。如果我关闭NSZombie,那么崩溃会回来。这是什么意思?我认为NSZombies被用来解决这种问题。如果NSZombie不会帮助,是否有另一种方式来询问这个过度释放的对象?

此外,模拟器上无法再现崩溃,这就是为什么我不能使用仪器与NSZombie。

Folowing是崩溃时的回溯。

#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 

回答

16

您描述的问题可能是几件事之一;你可能会过度释放一个对象,或者你可能会破坏内存。如果你损坏内存 - 特别是破坏对象的前几个字节 - 那么它很容易在自动释放池漏洞(或任何其他消息)中出现崩溃。

崩溃发生在设备上,但不是模拟器,也指向内存损坏。设备[ARM]与模拟器[i386]的体系结构完全不同,可能存在许多问题。

通常情况下,它不会表现得非常一致。

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

其次,你做任何一种生malloc调用?或者用数据填充缓冲区?这种崩溃最常见的原因是在缓冲区结束时运行。


#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]() 

(加入以上后,OP解决了这一问题,但 - 存档)

那一声跟踪是内存损坏的经典签名。也就是说,isa指针 - 一个指向实例类的对象中第一个指针的字节值 - 被踩踏了。这种情况通常发生在当您在对象之前溢出内存缓冲区时。如果它只是一个字节溢出,那么不同平台之间的行为可能会有所不同,因为malloc量子 - 分配的实际大小(你在一个平台上要求90个字节,你可能会得到96个。另一个是128) - - 不同的平台,甚至不同的版本。

特别是,isa被一个看起来足够像一个指针那样的运行时引用垃圾值的值跺住,然后试图将结果位置作为类的方法表处理。

任何时候如果发现崩溃是objc_msgSend*()函数之一的几帧,那么很可能是内存损坏,如果是这样,它几乎总是缓冲区溢出。

既然是容易做到的,它仍然是一个好主意,做一个测试通过僵尸检测赶上“有时候真的只是一个过度释放的情况下”。

+1

你的建议是对的。我有一个缓冲区溢出问题。你节省了我的时间,可能还有几天的调试。而且我正在努力寻找不存在的过度销售。非常感谢。 – Morrowless 2011-01-31 08:56:08