Question

I was having trouble symbolicating some code in distribution build and finally created a simple project which has a button that basically causes a crash by accessing an objectAtIndex in an array that doesn't exist.

In release (or distribution) build the trace comes up like this when symbolicated where MyApp function calls are completely missing:

0- CoreFoundation                   0x34dcb29e __exceptionPreprocess + 158
1   libobjc.A.dylib                 0x3537397a objc_exception_throw +26 
2   CoreFoundation                  0x34d16b70 -[__NSArrayM objectAtIndex:] + 160 
3   UIKit                           0x311a40a0 -[UIApplication endAction:to:from:forEvent:] + 68
4   UIKit                           0x311a4052 -[UIApplication sendAction:toTarget:fromSender:forEvent:]   + 26 
5   UIKit                           0x311a4030 -[UIControl sendAction:to:forEvent:] + 40     
6   UIKit                           0x311a38e6 -[UIControl(Internal) _sendActionsForEvents:withEvent:] +   498
...

In debug build it shows MyApp functions where the code causing the crash is:

0   CoreFoundation                  0x34dcb29e __exceptionPreprocess + 158
1   libobjc.A.dylib                 0x3537397a objc_exception_throw + 26
2   CoreFoundation                  0x34d16b70 -[__NSArrayM objectAtIndex:] + 160
3   MyApp                           0x00098128 -[ViewController processArray] (ViewController.m:58)
4   MyApp                           0x0009814e -[ViewController Crash:](ViewController.m:63)**
5   UIKit                           0x311a40a0 -[UIApplication sendAction:to:from:forEvent:] + 68
6   UIKit                           0x311a4052 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 26
7   UIKit                           0x311a4030 -[UIControl sendAction:to:forEvent:] + 40
8   UIKit                           0x311a38e6 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 498

The above traces are off the device logs after performing identical tests of deploying and clicking on the button.

Several articles/blogs/questions on SO have talked about symbolication issues where hex symbols are shown instead of method name etc (which is different from this problem) and I've tried deleting stuff from derived data, cleaned out the build directory etc but this can be consistently reproduced. Can anyone please explain why this is happening.

EDIT: Adding the code for easy reference:

-(void) processArray
{
    NSMutableArray *array = [NSMutableArray arrayWithObjects:@"One", @"Two", @"Three", nil];
    [array objectAtIndex:3];//Intentional crash for testing
}

- (IBAction)Crash:(id)sender 
{    
    [self processArray];
}
Was it helpful?

Solution

Try turning off compiler optimizations and reproducing the crash in the release build.

I suspect that you are getting bitten by a tail call optimization. The compiler may issue instructions that JMP directly from the end of your method to whatever method is called.

i.e. in this case:

 - (void)boo
 {
    [self bangAGong];
 }

Since there is no return value, etc... the compiler can rewrite the call to bangAGong such that it reuses the current stack frame. This is called tail calling (and is also how objc_msgSend() works. By doing this, it eliminates a pop of the frame on return.

This makes your code run slightly faster, but also means that it'll appear like stack frames are dropped from crash reports.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top