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

use*_*039 10 xcode ios lldb

我是lldb的新手并试图通过使用来诊断错误 po [$eax class]

UI中显示的错误是:

Thread 1: EXC_BREAKPOINT (code=EXC_i386_BPT, subcode=0x0)
Run Code Online (Sandbox Code Playgroud)

这是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.
Run Code Online (Sandbox Code Playgroud)

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

Jim*_*ham 8

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

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

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

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

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

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

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

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

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

(lldb) po [$rax class]
Run Code Online (Sandbox Code Playgroud)

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

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

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


小智 6

我正在添加我的解决方案,因为我一直在努力解决同样的问题,但我没有在任何地方找到这个解决方案。

就我而言,我必须运行 Product -> Clean Build Folder(Clean + Option 键)并重建我的项目。断点和 lldb 命令开始正常工作。


Gob*_*i M 6

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