ChatGPT解决这个技术问题 Extra ChatGPT

Xcode 4.2 调试不象征堆栈调用

我在 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)

谢谢。


Z
Zane Claes

我尝试过的任何方法都无法解决此问题(尝试了两个编译器、两个调试器等)。在为 iOS 5 更新升级 XCode 之后,似乎没有堆栈跟踪工作。

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

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

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

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

而已!

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

有些东西正在覆盖您的 NSSetUncaughtExceptionHandler 调用(整个应用程序只能有一个处理程序)。例如,一些 3rd 方库设置了自己的 uncaughtExceptionHandler。因此,请尝试在您的 didFinishLaunchingWithOptions 函数的末尾设置它(或有选择地禁用第 3 方库)。或者更好的是,在 NSSetUncaughtExceptionHandler 上设置一个符号断点以快速查看是谁在调用它。您可能想要做的是修改您当前的而不是添加另一个。您实际上并没有遇到异常(例如, EXC_BAD_ACCESS 不是异常;感谢@Erik B 的评论,如下)


很高兴听到它:) 我发现将崩溃日志写入文件并提示用户在下次启动时提交它很有用(仅在发布模式下,不会妨碍调试)。这让我得到了很好的错误报告......并且用户知道他们的问题正在得到解决:)
这似乎不起作用 - uncaughtExceptionHandler 例程从未被调用。
您能否更具体地说明如何使用它?它似乎对我不起作用。
非常可悲的 xCode 没有为我们显示这个。
非常感激!令人费解的是,Apple 没有在 IDE 中实现这种基本功能。
W
WiseOldDuck

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

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

如果您确实想要一个适合复制/粘贴等的符号化调用堆栈,gdb 回溯将从那里正常工作:

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

(ETC)


到目前为止,这对我来说非常有效。调试器现在在崩溃线上停止,不需要回溯。
这对我也很有效。非常感谢,没有这个断点我快疯了......
+1 因为它有效。它不会给你一个很好的错误消息来解释异常的原因,但它是一个开始......
你是我的 HotD @WiseOldDuck。
这为我恢复了预期的行为。注意:还记得在新项目上重新添加此断点!
P
Pedro

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

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

就这样!

PS:在某些情况下,仅针对 Objective-C 异常进行中断会更好。


这绝对是我的解决方案。
这对我来说是个问题。我和一位同事共享同一个 Xcode 项目,我问他是否有问题,他没有。不同之处在于他的项目打破了 Objective-c 异常 (objc_exception_throw)
你只是帮助找到了一个无法追踪的错误。太感谢了。我一直在到处寻找这样的东西。
这就像一个魅力!这正是我正在寻找的,这比添加异常处理程序要好,因为添加断点可以将您带到引发异常的正确位置,异常处理程序可以工作,但只是给您一个想法。
A
Alexander

这是另一种解决方案,不像以前那么优雅,但如果你没有添加异常断点或处理程序,它可能只是一种方法。
当应用程序崩溃,你得到你的原始第一次抛出调用堆栈(十六进制数字),输入 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(在这种情况下不带星号),您会得到类似的输出。

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

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

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

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


M
MonsieurDart

您可以添加 Exception Breakpoint(使用 Breakpoint Navigator 底部的 +)并向其添加操作 bt(单击 Add Action 按钮,选择 Debugger命令,在文本字段中输入“bt”)。一旦抛出异常,这将显示堆栈跟踪。


l
logancautrell

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

在此处提交错误报告。

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

编辑:

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


是的,我尝试切换编译器,但问题仍然存在。但无论如何谢谢:)
他建议切换调试器,而不是编译器。
仅供参考:在这种情况下,它与您使用的编译器或调试器的版本无关。这是 iOS 控制台输出的变化。
有趣的是,这方面的经历有多少不同——我认为存在一些问题。我无法让调试器在异常断点处停止。从 GDB 切换到 LLDB 解决了这个问题。
F
Flexo

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

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

这似乎不适用于情节提要。 2012-06-04 20:34:52.211 问题[1944:207] 如果要使用主情节提要文件,应用程序委托必须实现窗口属性。 2012-06-04 20:34:52.213 问题[1944:207] 应用程序在应用程序启动结束时应该有一个根视图控制器
M
Matt Connolly

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

图像查找-a 0x1234

它会向您显示类似的内容:

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

谢谢,我真的在找这个。令人惊讶的是,没有将整个“第一次抛出调用堆栈”显示为调用堆栈的快捷方式,因为我想可以轻松编写 Python lldb 脚本。
B
Bradweiser86

重新打开“Compile for Thumb”(调试配置)对我有用。


关注公众号,不定期副业成功案例分享
关注公众号

不定期副业成功案例分享

领先一步获取最新的外包任务吗?

立即订阅