Sometimes (meaning quite often) when I try to debug crashes from an iPad App, LLDB decides not to be too helpful and printing of variables (stack or class members) fails to work.
If I right-click (or CTRL+click) a variable in the debug window on the left and then "Print description" I get error messages like the following:
Printing description of error:
(NSURLError *) error = <register sp is not available>
or
Printing description of error:
(NSURLError *) error = <register ebp is not available>
If I try to use the debug console myself I get something like this:
(lldb) po error
(NSError *) $3 = 0x2124fc10 [no Objective-C description available]
Afterwards the right click seems to start working and yields the following:
Printing description of error:
(NSURLError *) error = 0x2124fc10
But all I get is the memory address, it fails to call description on it it seems.
If I try to send the description message this happens:
(lldb) po [error description]
error: Execution was interrupted.
The process has been returned to the state before execution.
So this is not helpful either. What can be done to make the debugger usable again? I desperately have to catch a crash but everytime I can provoke it the above happens and I have no clue how to get to the error's core.
I googled for "register not available lldb" but found nothing, just some pastebin logs, no answers.
FYI: Using Xcode 4.5.2, iOS SDK 6.0, compiling "Debug"-Profile, no optimizations turned on, LLDB Debugger, iOS deployment target 5.0, happens on debugging in Simulator or on device (iPad 1 and 3, iPhone 4S, iPhone 3GS), debugged App is using GCD quite extensively.
You're hitting a bug in the lldb in Xcode 4.5.x with its volatile register list on i386.
Registers fall in to two classes: volatile and non-volatile (or callee-saved). When a function calls another function, all of the "volatile" registers may have their contents overwritten. All non-volatile/callee saved registers will be preserved by the called function (callee function) before they are reused, and their previous values restored before returning.
Sometimes the debug info will say that a variable is stored in a volatile register. If that function is in the middle of your stack and you want to examine that variable, the debugger cannot reconstruct that register's value -- it is lost. gdb would simply copy the volatile register's value up to the middle of the stack and print the variable with a (potentially) bogus value, leading developers to be very confused.
lldb knows the difference between volatile and non-volatile registers and won't let volatile registers be reused in the middle of a stack like that -- they'll say that the register value is unavailable instead.
Unfortunately in this case, you're seeing lldb claim it cannot reconstruct variables that are available. They are mis-categorized as volatile when they should be non-volatile. Without doing a lot of assembly-language inspection, this is not going to be easy for you to work around. The only solution here is to resume execution until you're back in that function again (i.e. it is now frame 0) and then all of the register values will be correctly marked as available.
This is fixed in Xcode 5, released September 2013.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With