Debugging Smashed Memory in Obj-C

April 24, 2013

We were getting a crash inside a button. Calling po self wasn’t helpful.

(lldb) po self
$1 = 0x0ce854d0 [no Objective-C description available]

Well.. That’s weird. I wonder what’s at that memory location?

(lldb) memory read 0x0ce854d0
0x0ce854d0: 00 00 00 b0 93 6a ce a0 0e 00 00 00 00 00 00 00  .....j..........
0x0ce854e0: 10 c7 e7 0c 00 00 00 00 00 00 00 00 00 00 00 00  ................

That… doesn’t look right. Let’s turn on some debugging tools and see if that helps. Open the ‘Edit Scheme’ window and navigate to the Diagnostics tab. You’ll want to turn on “Enable Scribble” and “Malloc Stack”. You can read more about these methods here, but in short, “Enabled Scribble” will cause the allocator to write 0xAA to newly allocated memory and write 0x55 to deallocated memory. “Malloc Stack” will log the allocation and free history of your memory.

debugging settings

Let’s get our app to crash again and see if that helped.

(lldb) po self
$1 = 0x0cdcd2d0 [no Objective-C description available]
(lldb) memory read 0x0cdcd2d0
0x0cdcd2d0: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55  UUUUUUUUUUUUUUUU
0x0cdcd2e0: 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55 55  UUUUUUUUUUUUUUUU

Well, there we go. Obviously someone else is freeing self while we’re in the middle of a method. Let’s grab the PID of our crashing process. Easiest way to get this from an iOS app is to check out any log statements in the terminal.

2013-04-22 10:59:38.194 Sing![14105:2203] Loggin'

Mosey on over to your trusty terminal and let’s see what’s happening at that memory address.

$ malloc_history 14105 0x0cdcd2d0

This is going to fill your screen with a massive spew of text. You’ll probably want to pipe the results to your text editor of choice. The important bits are right there at the top, though. Check it out:

ALLOC ... 
FREE  0xcdcd2d0-0xcdcd3a7 ... CFRunLoopTimerInvalidate | _timerRelease | ... -[SongPreviewButton dealloc] ... free

About 100 lines of junk omitted. But there you go. We’ve got a timer that’s holding on to a button, preventing it from being freed when it should be, then all of a sudden the timer lets go and everything falls apart. Simple!

« | Home | »