Xcode 4.2debugging不象征堆栈调用

我在iOS 5模拟器/设备中debuggingXcode 4.2时遇到问题。 按预期,以下代码崩溃:

NSArray *arr=[NSArray array]; [arr objectAtIndex:100]; 

在iOS 4中,我得到了hex数字的有用堆栈跟踪。 但在iOS 5中,它只是给了我:

 *** First throw call stack: (0x16b4052 0x1845d0a 0x16a0674 0x294c 0x6f89d6 0x6f98a6 0x708743 0x7091f8 0x7fcaa9 0x2257fa9 0x16881c5 0x15ed022 0x15eb90a 0x15eadb4 0x15eaccb 0x6f02a7 0x6faa93 0x2889 0x2805) 

谢谢。

没有什么我试过会解决这个问题(尝试编译器,两个debugging器等)升级XCode为iOS 5更新后,没有堆栈跟踪似乎工作。

但是,我find了一个有效的解决办法 – 创build我自己的exception处理程序(这也是其他原因有用)。 首先,创build一个函数来处理错误并将其输出到控制台(以及任何你想要做的事情):

 void uncaughtExceptionHandler(NSException *exception) { NSLog(@"CRASH: %@", exception); NSLog(@"Stack Trace: %@", [exception callStackSymbols]); // Internal error reporting } 

接下来,将exception处理程序添加到您的应用程序委托:

 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler); // Normal launch stuff } 

而已!

如果这不起作用,那么只有两个可能的原因

  1. 有些东西正在覆盖你的NSSetUncaughtExceptionHandler调用(你的整个应用程序只能有一个处理程序)。 例如,一些第三方库设置了自己的uncaughtExceptionHandler。 因此,请尝试在didFinishLaunchingWithOptions函数的END处设置它(或者select性地禁用第三方库)。 或者更好的是,在NSSetUncaughtExceptionHandler上设置一个符号断点,以便快速查看谁在调用它。 你可能想要做的是修改你当前的一个,而不是添加另一个。
  2. 您实际上并没有遇到exception(例如, EXC_BAD_ACCESS 不是一个例外;请注意下面的@Erik B的注释)

有一个添加exception断点的有用选项(使用断点导航器底部的+)。 这将打破任何例外(或者你可以设置条件)。 我不知道这个select在4.2是否是新的,或者我只是终于注意到它试图解决缺less的符号问题。

一旦你命中了这个断点,你可以像平常一样使用Debug Navigator导航调用堆栈,检查variables等等。

如果你想要一个符号化的调用堆栈适合复制/粘贴或类似的,gdb回溯将从这里工作正常:

 (gdb) bt #0 0x01f84cf0 in objc_exception_throw () #1 0x019efced in -[NSObject doesNotRecognizeSelector:] () 

(等等)

debugging器上有一个新function。 每当引发exception时,您都可以设置一个中断点,并在那里停止执行,就像它曾经发生在4.0上一样。

在“Breakpoint Navigator”中,添加一个“Exception Breakpoint”,然后在popup的选项上按“Done”。

就这样!

PS:在某些情况下,最好只打破Objective-Cexception。

这里还有一个解决scheme,不像以前那么优雅,但是如果你没有添加exception断点或处理程序,它可能只是一个方法。
当应用程序崩溃,你得到你的原始第一个抛出调用堆栈 (hex数字),键入Xcode控制台info line *hex (不要忘记明星和0xhex说明符),例如:

 (gdb) info line *0x2658 Line 15 of "path/to/file/main.m" starts at address 0x25f2 <main+50> and ends at 0x267e <main+190>. 

如果你正在使用lldb ,你可以inputimage lookup -a hex -hex (在这种情况下没有星号),你会得到类似的输出。

使用这种方法,您可以从抛出堆栈的顶部(将有大约5-7个系统exception传播器)遍历导致崩溃的函数,并确定确切的文件和代码行。

此外,类似的效果,你可以在terminal使用atos工具,只需键入:

 atos -o path/to/AplicationBundle.app/Executable 0xAdress1 0xAdress2 0xAdress3 ... 

并得到符号化的堆栈跟踪(至less对于有debugging符号的函数)。 这种方法是更可取的,因为你不必为每个地址info line ,只需从控制台输出复制地址,并将其粘贴到terminal。

您可以添加一个exception断点 (使用断点导航器底部的+)并添加动作 bt (单击添加动作button,selectdebugging器命令,在文本字段中input“bt”)。 一旦抛出exception,这将显示堆栈跟踪。

这是一个常见的问题,没有得到4.2的堆栈跟踪。 您可以尝试在LLDB和GDB之间进行交换,以查看是否获得更好的结果。

在这里提交错误报告。

http://developer.apple.com/bugreporter/

编辑:

我相信,如果你换回到LLVM GCC 4.2,你不会看到这种情况发生。 你可能会失去你需要的function。

在你的主要function中使用这个代码:

 int main(int argc, char *argv[]) { NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; int retVal; @try { retVal = UIApplicationMain(argc, argv, nil, nil); } @catch (NSException *exception) { NSLog(@"CRASH: %@", exception); NSLog(@"Stack Trace: %@", [exception callStackSymbols]); } @finally { [pool release]; } return retVal; } 

在Xcode的debugging控制台提示符下键入:

image lookup -a 0x1234

它会告诉你这样的事情:

  Address: MyApp[0x00018eb0] (MyApp.__TEXT.__text + 91088) Summary: MyApp`-[MyViewController viewDidAppear:] + 192 at MyViewController.m:202 

重新打开“为Thumb编译”(​​debuggingconfiguration)为我工作。