adventures in ios crash land
Tue, Feb 8, 2011
I’ve been working on CBLocation to get OS grid references from iPhone latitude/longitude and all the unit tests were working fine and importing the static library into a test app worked fine both on the simulator and the phone. However, when I ran the app independently on the phone it immediately crashed. Luckily, there’s a way to look at what happened, although it’s not very pretty.
First you need the crash logs from the phone. Plug it into the machine, fire up iTunes and do a sync and I found the crash logs in:
~/Library/Logs/CrashReporter/MobileDevice/Alistair’s iPhonewith a name along the lines of:
CBLocationTest_2011-02-08-221002_Alistairs-iPhone.crashThe crash log is pretty useless without the dSYM file from the build, so what I did was clear out the crash logs directory, then run the app on the phone to get it to crash, then sync it and retrieve the single crash file. I then copied the crash file and the dSYM file:
CBLocationTest.app.dSYMto a separate crash directory I made. The next piece of the jigsaw is to locate symbolicatecrash. Mine was in:
/Developer/Platforms/iPhoneOS.platform/Developer/Library/PrivateFrameworks/DTDeviceKit.framework /Versions/A/Resources/symbolicatecrashThen it’s just a case of symbolicating the crash log:
symbolicatecrash CBLocationTest_2011-02-08-221002_Alistairs-iPhone.crash CBLocationTest.app.dSYM > reportThis is what appeared first:
Thread 0 Crashed: 0 libSystem.B.dylib 0x311de2d4 __kill + 8 1 libSystem.B.dylib 0x311de2c4 kill + 4 2 libSystem.B.dylib 0x311de2b6 raise + 10 3 libSystem.B.dylib 0x311f2d72 abort + 50 4 libSystem.B.dylib 0x311e2b9e szone_error + 222 5 libSystem.B.dylib 0x311e2c6a free_tiny_botch + 58 6 libSystem.B.dylib 0x31167590 szone_free + 328 7 libSystem.B.dylib 0x31167430 malloc_zone_free + 60 8 CoreFoundation 0x3143742c __CFAllocatorSystemDeallocate + 8 9 CoreFoundation 0x31433512 CFAllocatorDeallocate + 90 10 CoreFoundation 0x3143b51a _CFRelease + 266 11 CoreFoundation 0x3143b3d6 CFRelease + 82 12 CoreFoundation 0x3143a8d8 _CFAutoreleasePoolPop + 140 13 Foundation 0x31cc8326 NSPopAutoreleasePool + 2 14 UIKit 0x338a0502 _wrapRunLoopWithAutoreleasePoolHandler + 34 15 CoreFoundation 0x31460c52 CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION + 10 16 CoreFoundation 0x31460ac6 __CFRunLoopDoObservers + 406 17 CoreFoundation 0x314580c4 __CFRunLoopRun + 848 18 CoreFoundation 0x31457c80 CFRunLoopRunSpecific + 224 19 CoreFoundation 0x31457b88 CFRunLoopRunInMode + 52 20 GraphicsServices 0x35d664a4 GSEventRunModal + 108 21 GraphicsServices 0x35d66550 GSEventRun + 56 22 UIKit 0x338d5322 -[UIApplication _run] + 406 23 UIKit 0x338d2e8c UIApplicationMain + 664 24 CBLocationTest 0x00002d20 main (main.m:14) 25 CBLocationTest 0x00002cd4 start + 32The action around malloc_zone_free and szone_error led me to believe there was a bit of a kerfuffle going on with memory management and sure enough, I was releasing an autoreleased NSString. Fixed that and it still crashed, so I went through the crash log process again and this time was presented with this lot:
Thread 0 Crashed: 0 libobjc.A.dylib 0x3199f466 objc_msgSend + 18 1 CoreFoundation 0x3143a8d8 _CFAutoreleasePoolPop + 140 2 Foundation 0x31cc8326 NSPopAutoreleasePool + 2 3 UIKit 0x338a0502 _wrapRunLoopWithAutoreleasePoolHandler + 34 4 CoreFoundation 0x31460c52 CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION + 10 5 CoreFoundation 0x31460ac6 __CFRunLoopDoObservers + 406 6 CoreFoundation 0x314580c4 __CFRunLoopRun + 848 7 CoreFoundation 0x31457c80 CFRunLoopRunSpecific + 224 8 CoreFoundation 0x31457b88 CFRunLoopRunInMode + 52 9 GraphicsServices 0x35d664a4 GSEventRunModal + 108 10 GraphicsServices 0x35d66550 GSEventRun + 56 11 UIKit 0x338d5322 -[UIApplication _run] + 406 12 UIKit 0x338d2e8c UIApplicationMain + 664 13 CBLocationTest 0x00002c48 main (main.m:14) 14 CBLocationTest 0x00002bfc start + 32This time it looked like the autorelease pool was having a hissy fit. Sorry pool! Prolly my code at fault, so I dug into the CBLocation code and had a doh! moment after quite a lot of head scratching:
NSString* gridRef = [[NSString stringWithFormat:@“%@%@ %d %d”, firstGridLetter, secondGridLetter, easting, northing] autorelease];I’d forgotten the golden rules of iOS memory management. Only release if you own it. I’d actually autoreleased an NSString generated with stringWithFormat. I didn’t use “new”, or any variant of “init” so I shouldn’t have been doing anything about releasing the object. I fixed that and now it’s all working just fine!
This was a handy reference along the way.