3

有时(意味着经常)当我尝试从 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.

所以这也没有帮助。可以做些什么来使调试器再次可用?我迫切地不得不赶上崩溃,但每次我可以引发它时,都会发生上述情况,我不知道如何找到错误的核心。

我用谷歌搜索“注册不可用的 lldb”,但什么也没找到,只有一些 pastebin 日志,没有答案。

仅供参考:使用 Xcode 4.5.2,iOS SDK 6.0,编译“Debug”-Profile,没有打开优化,LLDB 调试器,iOS 部署目标 5.0,发生在模拟器或设备(iPad 1 和 3,iPhone 4S,iPhone 3GS),被调试的App相当广泛地使用GCD。

4

1 回答 1

9

您在 Xcode 4.5.x 的 lldb 中遇到了一个错误,它在 i386 上具有易失性寄存器列表。

寄存器分为两类:易失性和非易失性(或被调用者保存)。当一个函数调用另一个函数时,所有“易失性”寄存器的内容都可能被覆盖。所有非易失性/被调用者保存的寄存器在被重用之前将由被调用函数(被调用函数)保存,并在返回之前恢复它们之前的值。

有时调试信息会说变量存储在易失性寄存器中。如果该函数位于堆栈的中间并且您想要检查该变量,则调试器无法重建该寄存器的值——它会丢失。gdb 会简单地将 volatile 寄存器的值复制到堆栈的中间,并使用(可能)虚假值打印变量,导致开发人员非常困惑。

lldb 知道易失性和非易失性寄存器之间的区别,并且不会让易失性寄存器像那样在堆栈中间被重用——他们会说寄存器值不可用。

不幸的是,在这种情况下,您会看到 lldb 声称它无法重建可用的变量。当它们应该是非易失性时,它们被错误地归类为易失性。如果不进行大量汇编语言检查,您将很难解决这个问题。这里唯一的解决方案是恢复执行,直到您再次返回该函数(即现在是第 0 帧),然后所有寄存器值都将正确标记为可用。

这在 2013 年 9 月发布的 Xcode 5 中得到了修复。

于 2012-12-04T22:16:50.060 回答