Neither one of these statements can be processed by LLDB... why is it unable to come up with the NSString result and print it out
expr -o -- [NSString stringWithFormat:@"%@", @"Wow this doesnt work??"]
po [NSString stringWithFormat:@"%@", @"Wow this doesnt work??"]
It seems that the expression command in lldb can generally not evaluate functions with
variable argument lists. It fails even with a simple C function:
int foo(char *msg, ...)
{
return 17;
}
(lldb) expr foo("bar")
(int) $2 = 17
(lldb) expr foo("bar", 2)
error: no matching function for call to 'foo'
note: candidate function not viable: requires 1 argument, but 2 were provided
error: 1 errors parsing expression
So this looks like a bug (or non-feature) in lldb.
This is more of academic than practical interest, but the original question and Martin's answer actually have different causes. In both cases, lldb is actually correctly refusing to call a function with more arguments than it is declared to have, but getting the actual definition wrong for different reasons.
In the first case, lldb doesn't actually have debug information for the method call [NSString stringWithFormat:format, ...]. It turns out the compiler does not emit debug information for every function your program USES, only the ones it defines. This restriction is mostly to keep the size of the debug information manageable.
So the debugger has to consult the ObjC runtime for extra type information for these kit functions. But the runtime type information doesn't encode the variable argument-ness of variable argument functions.
In the second case, what you are seeing is actually a bug in clang's debug output. It fails to emit the bit of information that tells the debugger that the function is a variable argument function.
In any case, in lldb you can work around this sort of issue by introducing declarations of commonly used functions to lldb's expression parser using the "expr-prefix" file. For instance, in Martin's case, I make a file "/tmp/expr-prefix.lldb" containing the line:
extern "C" int foo (char *msg, ...);
Then in lldb, I do:
(lldb) settings set target.expr-prefix /tmp/expr-prefix.lldb
And then you can call the function in the expression parser. A couple of caveats with this feature. This "expression prefix" file gets included in all the expression you run with the "print" command, so don't put too much stuff in there or it will slow down general expression parsing. Don't try to do things like:
#import <Cocoa/Cocoa.h>
that will be very slow and probably won't work anyway - since this depends on a whole set of #defines that the debugger doesn't know about.
But it can be very helpful if you have a few functions like this that you really need to call, but can't because we either don't know the signature or are somehow getting it wrong.
The extern "C" is required because lldb parses expressions as ObjC++.
If you want to prototype an ObjC method, you need to do it on an extension of the class you are prototyping the method for; we often have a rudimentary class def'n and the compiler doesn't like to add methods to a known class, only extensions.
I found a workaround in this article:
http://www.cimgf.com/2012/12/13/xcode-lldb-tutorial/
For example when I try to use this syntax to call method:
po [NSString stringWithFormat:@"%@", @"MyName"];
Debugger error is:
error: too many arguments to method call, expected 1, have 2
error: 1 errors parsing expression
But you can try this one:
po [[NSString alloc] initWithFormat:@"%@", @"MyName"];
Debugger message is:
$4 = 0x0a6737f0 MyName
import UIKit in debugger this worked for me
expr @import UIKit