执行被中断,原因:EXC_BAD_ACCESS(代码= 1,地址= 0xb06b9940)

时间:2014-11-18 05:28:02

标签: ios xcode lldb

我是lldb的新手并尝试使用po [$eax class]

来诊断错误

UI中显示的错误是:

Thread 1: EXC_BREAKPOINT (code=EXC_i386_BPT, subcode=0x0)

这是lldb控制台,包括我输入的内容和返回的内容:

(lldb) po [$eax class]
error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=1, address=0xb06b9940).
The process has been returned to the state before expression evaluation.

全局断点状态切换已关闭。

3 个答案:

答案 0 :(得分:5)

你的应用程序正在停止,因为你运行的代码引发了一个未被捕获的Mach异常。 Mach异常相当于Mach内核的BSD信号 - 它构成了macOS操作系统的最低级别。

在这种情况下,特定的Mach异常为EXC_BREAKPOINTEXC_BREAKPOINT是混淆的常见原因......因为它有"断点"在名称中人们认为它是一个调试器断点。这并非完全错误,但例外情况比这更普遍。

EXC_BREAKPOINT实际上是Mach的较低层在执行某个指令(陷阱指令)时报告的例外情况。 lldb使用该陷阱指令来实现断点,但它也可以在各种系统软件中用作assert的替代。例如,如果您访问数组的末尾,则swift会使用此错误。这是一种在错误点停止程序的方法。如果您在调试器外运行,则会导致崩溃。但是如果您在调试器中运行,那么控件将以EXC_BREAKPOINT停止原因返回到调试器。

为避免混淆,如果陷阱是lldb插入到正在调试的程序中以实现调试器断点,则lldb永远不会向您显示EXC_BREAKPOINT作为停止原因。它总是会说breakpoint n.n

因此,如果您看到一个以EXC_BREAKPOINT作为停止原因而停止的线程,则意味着您已经遇到某种致命错误,通常是在您的程序使用的某些系统库中。此时的回溯将显示哪个组件引发了该错误。

无论如何,然后遇到了这个错误,你试图通过运行po [$eax class]来调用eax寄存器中的类方法来找出它的类。调用该方法(这将导致代码在您正在调试的程序中运行)导致崩溃。这是"错误"你引用的消息告诉你。

这几乎肯定是因为$eax没有指向有效的ObjC对象,所以你只是在某个随机值上调用一个方法,然后崩溃了

注意,如果你正在调试一个64位程序,那么$ eax实际上是真实参数传递寄存器的低32位 - $ rax。 64位指针的低32位不太可能是有效的指针值,因此调用class导致崩溃并不奇怪。

如果你试图在64位Intel的第一个传递的参数(在ObjC方法中自我)上调用类,你真的想做:

(lldb) po [$rax class]

请注意,这也不太可行,因为$rax仅在函数开头持有self。然后它被用作临时寄存器。因此,如果您进入该函数的任何方式(事实上您的代码致命失败,某些测试看起来很可能),$ rax将不太可能仍然保持self

另请注意,如果这是一个32位程序,那么$eax实际上并不用于参数传递 - 32位Intel代码在堆栈上传递参数,而不是寄存器。

无论如何,要弄清楚出错的第一件事就是在遇到此异常时打印回溯,并查看在发生此错误时运行的代码。

答案 1 :(得分:0)

我正在添加自己的解决方案,因为我一直在同一个问题中挣扎,却在任何地方都找不到此解决方案。

就我而言,我必须运行“产品”->“清理构建文件夹”(“清理+选项”键)并重建我的项目。断点和lldb命令开始正常工作。

答案 2 :(得分:0)

清理项目并重新启动Xcode对我有用。