lldb error: variable not available

13,716

Solution 1

This is an artifact of debugging optimized code. When the compiler's optimization is enabled in your build settings, it moves variables between memory and registers as it decides is best. At the point where you're examining the variable in lldb, it may not exist in registers or memory at all -- even though it looks like it should still be available for display.

It's possible it is a shortcoming of the debug information output by the compiler. Sometimes the compiler will copy a variable into a register for its use and only list that register location in the debug information. Later the register is repurposed for other uses; value is still present on the stack but the compiler hasn't told the debugger that the value can be found there.

The only way to really tell whether it's insufficient debug info or if the value genuinely doesn't exist at that particular instruction is to examine the assembly code by hand. As soon as you turn on optimization with the compiler, the source code becomes a weak view into what's actually being executed in any particular order.

Instead of wandering too far into the wacky world of optimized code debugging, I strongly recommend turning off optimization (Optimization Level in your Build Settings) for your build and debugging it that way, if at all possible. If you do need to debug your app with optimization, make sure you're building with the latest Apple LLVM compiler supported by your Xcode -- there is always work being done to improve optimized code debugging and you want to avail yourself of the most up to date tools you can.

Solution 2

The "Address Sanitizer" in the diagnostics seems to make the values of variables unavailable, too.

Schemes > Run > Diagnostics > Address Sanitizer

Solution 3

In Swift, possibly starting with Xcode 9 and still an issue in Xcode 10, this could even come up when code optimization is turned off in the build settings. As @carlos_ms has pointed out here, a temporary solution is to define the variable as mutable, i.e.

Turn

let foo = Bar().string

into

var foo = Bar().string

in order to cause optimization to skip on this variable. Note that this might not work in all instances.

In this case, a good ol' debugPrint() might help you out.

Share:
13,716
ari gold
Author by

ari gold

Updated on July 07, 2022

Comments

  • ari gold
    ari gold almost 2 years

    Here are my two lines of code:

    NSString *frontFilePath = [[NSBundle mainBundle] pathForResource:[self.bookendFileNames objectAtIndex:self.randomIndex] ofType:@"caf"];
    NSLog(@"frontFilePath = %@", frontFilePath );
    

    I put a break point on the second line and when there, I try to print it:

    (lldb) po frontFilePath
    

    But I get the following error:

    error: variable not available
    

    I'm confused because if I step over the NSLog statement, the variable does indeed print to the console.

    For what it's worth, I'm trying to debug the first line since sometimes it returns NULL, tho I can't, as of now, figure out why.

  • Jason Molenda
    Jason Molenda over 11 years
    BTW just to be clear -- I got sidetracked in the details in my answer -- what lldb is saying is that at this particular instruction point, it doesn't know how to find the value of your variable. The variable may not be available at that point, or the compiler's debug information may just be insufficiently descriptive, but there's nothing lldb can do at this point given what it has to work with.
  • ari gold
    ari gold over 11 years
    For what it's worth, Build Setting > Optimization Level was set to "none" in the "debug" category. It's set to "fastest, smallest" in the "release" category. I'm assuming that I'm in "debug" and not "release" but I'm not quite sure how to tell.
  • Luke
    Luke about 11 years
    I ran into this when in Release mode instead of Debug, thanks for this answer, helped me spot it more quickly and revert :)
  • Adam
    Adam over 10 years
    Great answer, helped a lot (likewise: running in Release, doing final testing). I suggest everyone logs a bug / whines at Apple to change this to an error message that says-what-it-means, instead of being meaningful only to people who write compilers and debuggers.
  • Paul Slocum
    Paul Slocum over 8 years
    I still have this problem sometimes even though optimization is definitely turned off.
  • onmyway133
    onmyway133 about 8 years
    @JasonMolenda I have Optimization turned off, and in Debug mode, but the problem is still there
  • carlos_ms
    carlos_ms over 7 years
    lets face it, swift sucks!... this is version 3!!!, not beta, not alpha... 3! and we're talking about Apple, the richest tech company in the "guuuooorl"
  • carlos_ms
    carlos_ms over 7 years
    Swift is so bad that if you have a variable with let will "opti-mi-ze it" because it thinks you don't want to modify it any longer so why bother to save a reference for you even if you have the optimization level to NONE. Change your lets for var's and it might -just might- work.
  • gprasant
    gprasant over 6 years
    @JasonMolenda by "Turn off optimization", do you mean - setting the Optimization Level for Debug configuration to 'None'?
  • gprasant
    gprasant over 6 years
    And also, looking in the Build settings, I found 'Apple LLVM 8.1 Optimization Level' & 'Swift Compiler Optimization Level'. Since I am seeing the problem mentioned in the Question in Obj-C code, Is changing the former setting enough ?
  • Eddie Sullivan
    Eddie Sullivan almost 6 years
    No, this happens even with optimization completely disabled.
  • Duck
    Duck about 5 years
    @carlos_ms - it is not swift that sucks it is Xcode, a subpar tool.