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 iPhone
with a name along the lines of:
CBLocationTest_2011-02-08-221002_Alistairs-iPhone.crash
The 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.dSYM
to 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/symbolicatecrash
Then it’s just a case of symbolicating the crash log:
symbolicatecrash CBLocationTest_2011-02-08-221002_Alistairs-iPhone.crash CBLocationTest.app.dSYM > report
This 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 + 32
The 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 + 32
This 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.

comments powered by Disqus