LLDB和“<register xy =”“is =”“not =”“available =”“>”</register>

时间:2012-12-04 16:05:49

标签: ios xcode debugging lldb

当我尝试从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。

1 个答案:

答案 0 :(得分:9)

您正在使用i386上的易失性寄存器列表在Xcode 4.5.x中的lldb中遇到错误。

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

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

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

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

这已在2013年9月发布的Xcode 5中修复。