Xcode 4.2 debug不符号堆栈调用

时间:2011-10-20 20:07:24

标签: ios xcode debug-symbols

我在iOS 5模拟器/设备中调试Xcode 4.2时遇到问题。以下代码崩溃,如预期的那样:

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

在iOS 4中,我获得了十六进制数的有用堆栈跟踪。但是在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)

感谢。

9 个答案:

答案 0 :(得分:255)

我尝试的任何东西都无法修复此问题(尝试了两个编译器,两个调试器等) 升级XCode以进行iOS 5更新后,似乎没有堆栈跟踪。

但是,我找到了一种有效的解决方法 - 创建自己的异常处理程序(由于其他原因也很有用)。首先,创建一个处理错误并将其输出到控制台的函数(以及您想要用它做的任何其他事情):

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

接下来,将异常处理程序添加到您的app delegate:

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

就是这样!

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

  1. 正在覆盖您的NSSetUncaughtExceptionHandler电话(整个应用只能有一个处理程序)。例如,某些第三方库设置了自己的uncaughtExceptionHandler。因此,尝试将其设置在didFinishLaunchingWithOptions函数的END(或选择性地禁用第三方库)。或者更好的是,在NSSetUncaughtExceptionHandler上设置一个符号断点,以便快速查看谁在调用它。您可能想要做的是修改当前的而不是添加另一个。
  2. 您实际上并未遇到异常(例如,EXC_BAD_ACCESS 是一个例外;感谢@Erik B的评论,如下所示)

答案 1 :(得分:109)

添加异常断点(使用断点导航器底部的+)有一个有用的选项。这将在任何异常中中断(或者您可以设置条件)。我不知道这个选择在4.2中是否是新的,或者我是否最终注意到它试图解决丢失的符号问题。

一旦你点击这个断点,就可以像往常一样使用Debug Navigator导航调用堆栈,检查变量等。

如果你想要一个适合复制/粘贴的符号化调用堆栈,gdb backtrace可以从那里正常工作:

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

(等)

答案 2 :(得分:46)

调试器上有一个新功能。您可以在抛出异常时设置断点,并在那里停止执行,就像以前在4.0上发生一样。

在“断点导航器”上,添加“异常断点”,然后在选项弹出窗口中按“完成”。

这就是全部!

PS:在某些情况下,最好只针对Objective-C例外进行破解。

答案 3 :(得分:21)

这是另一个解决方案,不像以前那么优雅,但如果你没有添加异常断点或处理程序,它只能是一种方法。
当应用程序崩溃,并且您获得原始第一个抛出调用堆栈(以十六进制数字表示)时,键入Xcode控制台info line *hex(不要忘记星号和0x十六进制说明符) ,例如:

(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 ,则可以输入image lookup -a hex(在这种情况下没有星号),并获得类似的输出。

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

此外,为了类似的效果,您可以在终端中使用atos实用程序,只需键入:

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

并且您获得符号化堆栈跟踪(至少对于具有调试符号的函数)。 这种方法更为可取,因为您没有每个地址调用info line,只需从控制台输出中复制地址并将其粘贴到终端。

答案 4 :(得分:9)

您可以添加例外断点(使用断点导航器底部的+)和添加操作 bt(单击添加操作按钮,选择Debugger Command,在文本字段中输入“bt”。一旦抛出异常,这将显示堆栈跟踪。

答案 5 :(得分:6)

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

在此处提交错误报告。

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

编辑:

我相信如果你换回LLVM GCC 4.2,你就不会发现这种情况。您可能会丢失所需的功能。

答案 6 :(得分:6)

在主要功能中使用此代码:

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;
}

答案 7 :(得分:6)

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

  

image lookup -a 0x1234

它会告诉你类似的东西:

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

答案 8 :(得分:1)

重新启用'Compile for Thumb'(调试配置)对我有用。

相关问题