3

I've created some example code to demonstrate my problem.

- (void) test {

    void (^handler)(void)  = ^ {

        NSArray *test = [NSArray array];
        [test objectAtIndex: 5];
    };

    handler = [handler copy];

    dispatch_async(dispatch_get_main_queue(), handler);
}

When I call the test method I don't get a stack trace. The debugger just stops at main.m and has this line highlighted

int retVal = UIApplicationMain(argc, argv, nil, NSStringFromClass([FantasyUniversalAppDelegate class]));

If I remove the dispatch_async and just call handler(); then I do get a stack trace. Can some one explain why this is and is there a way to get a more descriptive stack trace?

Right now I am using Flurry to show me crashes but the crashes it is showing me isn't very useful because I get a very non-descriptive stack trace (which is symbolicated). It looks like this:

Thread: Unknown Name
0     libsystem_kernel.dylib                0x3a224eb4 mach_msg_trap + 20
1     CoreFoundation                        0x32067045 __CFRunLoopServiceMachPort + 129
2     CoreFoundation                        0x32065d5f __CFRunLoopRun + 815
3     CoreFoundation                        0x31fd8ebd CFRunLoopRunSpecific + 357
4     CoreFoundation                        0x31fd8d49 CFRunLoopRunInMode + 105
5     GraphicsServices                      0x35b9c2eb GSEventRunModal + 75
6     UIKit                                 0x33eee301 UIApplicationMain + 1121
7     IOSTestApp                        0x00025d7b main (main.m:14)
SukyaMaki
  • 173
  • 1
  • 1
  • 5
  • I'm not 100%, but I believe that this is to do with the face that the exception is being raised ("index out of bounds"), is caught on the main thread. Your handler() block is being called on an alternate thread so the captured stack trace is not much use to you. When you just call handler() i is on the main thread so no problem. As to a solution, I'll get back to you! – George Green Aug 22 '13 at 13:09
  • You could wrap you code in a – George Green Aug 22 '13 at 13:10
  • Thanks but when trying that it gives me the method the block was called from but doesn't tell me the line number. It just says 0 IOSTestApp 0x0003428d __56-[DetailController tableView:cellForRowAtIndexPath:]_block_invoke + 173 – SukyaMaki Aug 22 '13 at 13:26
  • Sorry this is when you tried putting a try/catch around it? – George Green Aug 22 '13 at 13:28
  • 1
    Have you tried adding an exception breakpoint, as shown in this answer: http://stackoverflow.com/questions/18336920/strange-crash-nsrangeexception-with-unhelpful-stacktrace/18338022#18338022 – George Green Aug 22 '13 at 13:30

1 Answers1

0

You could wrap your code in a

@try {
    NSArray *test = [NSArray array];
    [test objectAtIndex: 5];
}
@catch {
    // Get the stack track for the current thread
    NSArray *stacktrace = [NSThread callStackSymbols];
    // Do something with the symbols
}

all within the block that you are dispatching. Though I'm sure there is a much nicer way!

George Green
  • 4,807
  • 5
  • 31
  • 45