【问题标题】:Xcode exception breakpoint doesn't print details of the exception being thrownXcode 异常断点不打印抛出异常的详细信息
【发布时间】:2013-06-18 18:54:00
【问题描述】:

总结

当我设置异常断点时,我没有收到异常消息。如何获取异常消息?我已经知道如何获取堆栈跟踪,但这不包括异常消息。

详情

过去我使用 Xcode 开发 iOS 应用程序,当出现问题时,我会收到错误/异常。异常通常会显示“无法取消引用 null”之类的消息。

现在,在过去几周使用 Xcode 4.6.x 时,我从未收到异常消息。我经常会得到一个 SIGABRT。我在异常断点处设置了中断,它会在那里中断,但它在 iOS SDK 的某些程序集中关闭,我从未收到消息。

事实上,我不记得上次在调试器控制台中看到任何内容是什么时候了。

异常信息是否随着向 LLVM 的迁移而消失?

让我的应用程序在 SDK 中崩溃而不知道原因是非常令人沮丧的。我检查最后一个函数以确保设置正确(分配的对象等)并且它们是正确的,这意味着我没有任何线索。

是否有可能是过去保留的构建设置以某种方式关闭了异常消息?

请重新提出问题。它现在有了答案!

在 cmets 中给出了很好的答案。这应该提升为完整答案,因此我可以标记已回答的问题,其他有此常见问题的人可以找到它。为了实现这一点,需要重新提出问题! (之后我会删除这个请求。)

【问题讨论】:

  • 你在这个断点有bt作为动作吗?右键单击 -> 编辑断点 -> 操作 -> 下拉菜单中的“调试器命令”,文本字段中的 bt。这应该在控制台中打印回溯。
  • 你只需要创建exception breakpoint
  • 如果设置了异常断点,那么在异常打印到控制台之前断点被命中。我解释了如何设置断点来打印异常here
  • 你看the link I gave earlier了吗?因为我对完全相同的问题感到沮丧,并且在 WWDC 2013 上我得到了一些 lldb 团队成员来帮助我解决它。我在该链接中解释了如何解决它。
  • 如果问题被重新打开,我会的。

标签: ios objective-c xcode


【解决方案1】:

我会在这里更新杰夫的答案:

同时突出显示导致异常的 (而不是 main.m 中的 UIApplicationMain())并查看 异常原因(例如,“错误:获取请求必须有一个实体。”),这样做:

  • 在断点导航器中:
    1. 添加 (+),添加异常断点
    2. 选择新断点,Control-Click,编辑断点
    3. 添加操作
    4. 输入:po $arg1

堆栈跟踪的相关部分将位于导航器区域。

这似乎在 Xcode 9 中仍然有效

这是我为 Xcode 6 及更低版本添加的内容。

  1. 输入:po (NSException*) $eax

在 Xcode 6 中,您必须显式提供对象类型,因为它不再被推断。

【讨论】:

  • 或者,您也可以进入控制台窗口,在调试控制台中输入 po (NSException*) $eax。
  • 重要提示:如果您正在创建 64 位应用程序,则不要使用 $eax,而是使用 $rax。 po (NSException*)$rax
  • 在 Xcode 6.3 中我得到结果错误:使用未声明的标识符 '$eax' - 与 rax 相同。我做错了吗?
  • 在 Xcode 8 中使用 Swift 时,po $arg1 会打印一个大数字,例如 106102873062904。这是什么意思?如何打印指向的字符串?
  • 最好编辑原始答案,而不是复制粘贴和补充。但是,可以确认:po $arg1 在 Xcode 9 上是成功的
【解决方案2】:

对于 Xcode 7-9(基于 Jeff 的回答):

在断点导航器中:

  1. 添加 (+),添加异常断点
  2. 选择新断点,Control-Click,编辑断点
  3. 添加操作
  4. 输入:po $arg1

【讨论】:

  • 这在 XCode 7.3 中显示“错误:使用未解析的标识符 '$arg1'”
  • Xcode 8, Swift 2.3,它打印出一个大数字。我应该在 Swift 中做什么?谢谢。
  • @DawnSong 这可能是 C++ 异常,您可能无需担心。
  • 感谢您的提示。正在使用 po $eax 并获得 nada。回报提示:如果您右键单击异常并向下滚动到将断点移动到并选择用户,则该异常适用于所有项目,而不仅仅是当前项目。保存一件小事,不必记住。
  • 如果在 Swift 中做 po $arg1 将不打印任何有用的信息,所以将异常部分从 All 更改为 Objective-C 。
【解决方案3】:

同时突出显示导致异常的 (而不是 main.m 中的 UIApplicationMain())并查看 异常原因(例如,“错误:获取请求必须有一个实体。”),这样做:

  • 在断点导航器中:
    1. 添加 (+),添加异常断点
    2. 选择新断点,控制点击,编辑断点
    3. 添加操作
    4. 输入:po $eax

堆栈跟踪的相关部分将位于导航器区域。

【讨论】:

  • 我在不止一个地方看到过这条建议......但它不再适用于 Xcode 6。
【解决方案4】:

是的,xcode 对调试不太友好。我喜欢这篇文章,它可以帮助我更清楚地理解崩溃日志)) Demystifying iOS Application Crash Logs

如果您看到错误“消息已发送到已释放的实例”,也请执行此操作

'产品 -> 编辑方案 -> 启用僵尸对象'

这将启用僵尸对象,当您对项目进行配置时选择 “僵尸”,导致错误,您将能够看到哪些对象被释放,例如 NSArray *myArray

【讨论】:

  • 有趣的是,“启用僵尸对象”下面的选项之一是“日志异常”,以前没有检查过。我已经检查过它是否可以解决问题。
【解决方案5】:

如果没有设置异常断点,我从 po $eaxpo (NSException *)$eax 获得的信息似乎与 Xcode 将打印的信息不同。所以我做了以下,

  1. 添加异常断点
  2. 出现异常,断点被命中 -> 我知道位置
  3. 暂时禁用断点(调试区域左侧的第二个按钮)
  4. 继续执行程序(Debug 区域左侧第三个按钮)
  5. 打印详细信息 -> 我知道原因

显然不是很优雅和灵活,但至少我回答了两个大问题(在哪里和为什么)。

【讨论】:

  • 感谢您的提示:“继续执行程序(调试区域左侧的第三个按钮)”我一直在重新启动应用程序并希望出现同样的异常。使用 Xcode 10。
【解决方案6】:

您可以使用btthread backtrace 命令打印错误跟踪

显示当前线程的堆栈回溯。

您可以在崩溃报告中找到相同的堆栈跟踪

当前线程使用信息currentThread

//Objective-C
po [NSThread currentThread]

//Swift
po Thread.currentThread

*当po 不工作时,有时您可以使用fr v(或者只是XCode 10.2 中的v

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-20
    • 2012-03-23
    • 2013-10-02
    • 2013-10-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多