Debugging super objects, a problem with NSZombie

EDIT : I found the cause of this accident! bbum noted that buffer overflows are a very common reason for this, so I looked at the only type of malloc buffer that I had:

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

I later rewrote the data outside the array, which should have been much larger than baseCells.count . Thank you bbum!

Question: During NSAutoreleasePool -drain, I have a playable EXC_BAD_ACCESS , which seems to indicate that I re-issue the object. So I turn on NSZombie , but then the program no longer crashes. I also do not receive information recorded on the console. If I turn off NSZombie, the accident will return. What does this mean? I thought NSZombies were used to solve just such a problem. If NSZombie does not help, is there any other way to interrogate this above object?

In addition, the crash on the Simulator does not play, so I can not use Tools with NSZombie.

Coverage is the return path at the point of failure.

 #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 
+4
source share
1 answer

The problem you are describing can be one of two things; you may oversubscribe an object, otherwise you may corrupt memory. If you damage memory - first of all, damage the first few bytes of an object, then this can easily occur as a result of a failure during the pool of the autorun pool (or any other message).

The fact that an accident occurs on the device, but not the simulator, also indicates a memory corruption. The architecture of the device [ARM] compared to the simulator [i386] is completely different, and there are some problems that may be in the game.

As a rule, he does not show himself so consistently.

First, place the back of the crash. This can help.

Secondly, are you making any raw malloc calls? Or filling buffers with data? The most common cause of such failures goes through the end of the buffer.


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

(Above was added after the OP fixed the problem, but - for the archive)

This failure trace is the classic signature for memory corruption. Namely, the isa pointer - the first pointer to bytes in the object that points to the instance class - stomped. This usually happens when you overflow the memory buffer in the distribution in front of the object. If this is just a couple of overflow bytes, then the behavior between different platforms may differ, since malloc quanta is the actual size of the distributions (you request 90 bytes on one platform, and you can get 96. Another? 128) - - differ between platforms and even releases .

In particular, isa was released with a value that looked enough like a pointer to the runtime dereferencing the garbage value, and then tried to treat the resulting location as a class method table.

Each time you see a crash that is several frames deep in one of the objc_msgSend*() functions, this is most likely a memory corruption, and if so, there will almost always be a buffer overflow.

Since it’s easy to do, it’s still nice to do a test run with zombie detection to catch β€œsometimes it’s really just release cases.”

+16
source

Source: https://habr.com/ru/post/1337725/


All Articles