有时(意思是经常)当我尝试从 iPad 应用程序调试崩溃时,LLDB 决定不太有用并且变量(堆栈或类成员)的打印无法工作。
如果我在左侧的调试窗口中右键单击(或按住 CTRL 单击)一个变量,然后“打印描述”,我会收到如下错误消息:
Printing description of error:
(NSURLError *) error = <register sp is not available>
或
Printing description of error:
(NSURLError *) error = <register ebp is not available>
如果我尝试自己使用调试控制台,我会得到如下结果:
(lldb) po error
(NSError *) $3 = 0x2124fc10 [no Objective-C description available]
然后右键单击似乎开始工作并产生以下内容:
Printing description of error:
(NSURLError *) error = 0x2124fc10
但我得到的只是内存地址,它似乎无法调用 description
。
如果我尝试发送 description
消息,会发生这种情况:
(lldb) po [error description]
error: Execution was interrupted.
The process has been returned to the state before execution.
所以这也没有用。 怎样做才能使调试器再次可用?我迫切需要捕获崩溃,但每次我可以引发它时,上述情况都会发生,我不知道如何找到错误的核心。
我用谷歌搜索“register not available lldb”但什么也没找到,只有一些 pastebin 日志,没有答案。
仅供引用:使用 Xcode 4.5.2、iOS SDK 6.0、编译“调试”-Profile、未打开优化、LLDB 调试器、iOS 部署目标 5.0,发生在模拟器或设备(iPad 1 和 3、iPhone 4S, iPhone 3GS), 被调试的 App 大量使用 GCD。
最佳答案
你在 Xcode 4.5.x 中的 lldb 中遇到了一个错误,它在 i386 上的 volatile 寄存器列表。
寄存器分为两类: volatile 和非 volatile (或被调用者保存)。当一个函数调用另一个函数时,所有“ volatile ”寄存器的内容都可能被覆盖。所有非 volatile /被调用者保存的寄存器在被调用函数(被调用者函数)重新使用之前将被保存,并且在返回之前恢复它们之前的值。
有时调试信息会说变量存储在 volatile 寄存器中。如果该函数位于堆栈的中间并且您想要检查该变量,则调试器无法重建该寄存器的值——它丢失了。 gdb 会简单地将 volatile 寄存器的值复制到堆栈的中间,并使用(可能)伪造的值打印变量,导致开发人员非常困惑。
lldb 知道 volatile 和非 volatile 寄存器之间的区别,不会让 volatile 寄存器像那样在堆栈中间重复使用——他们会说寄存器值不可用。
不幸的是,在这种情况下,您会看到 lldb 声称它无法重建可用的变量。当它们应该是非 volatile 时,它们被错误地归类为 volatile 。如果不进行大量的汇编语言检查,这对您来说并不容易解决。此处唯一的解决方案是恢复执行,直到您再次返回该函数(即现在是第 0 帧),然后所有寄存器值将被正确标记为可用。
这已在 2013 年 9 月发布的 Xcode 5 中修复。
关于ios - LLDB 和 "<register XY is not available>",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13706990/