I know I can type print someFloatVariable
when I set a breakpoint or po [self someIvarHoldingAnObject]
, but I can't do useful things like:
[self setAlpha:1];
Then it spits out:
error: '[self' is not a valid command.
Weird thing is that I can call po [self someIvarHoldingAnObject]
and it will print it's description.
I believe I've seen a video a year ago where someone demonstrated how to execute code through the console at runtime, and if I am not mistaken this guy also provided arguments and assigned objects to pointers. How to do that?
Both GDB and LLDB are of course excellent debuggers without doubt. GDB is debugger part of the GNU project created to work along the GNU compiler. LLDB is debugger part of the LLVM project created to work along LLVM compiler. The majority of the commands are the same.
In brief, LLDB and GDB are two debuggers. The main difference between LLDB and GDB is that in LLDB, the programmer can debug programs written in C, Objective C and C++ while, in GDB, the programmer can debug programs written in Ada, C, C++, Objective C, Pascal, FORTRAN and Go.
The canonical reference for gdb v. lldb commands is http://lldb.llvm.org/lldb-gdb.html
You want to use the expr command which evaluates an expression. It's one of the lldb commands that takes "raw input" in addition to arguments so you often need a "--" to indicate where the arguments (to expr) end and the command(s) begin. e.g.
(lldb) expr -- [self setAlpha:1]
There is a shortcut, "p", which does the -- for you (but doesn't allow any arguments), e.g.
(lldb) p [self setAlpha:1]
If the function(s) you're calling are not part of your program, you'll often need to explicitly declare their return type so lldb knows how to call them. e.g.
(lldb) p printf("hi\n") error: 'printf' has unknown return type; cast the call to its declared return type error: 1 errors parsing expression (lldb) p (int)printf("hi\n") (int) $0 = 3 hi (lldb)
There is a neat way to work around the floating point argument problem, BTW. You create an "expression prefix" file which is added to every expression you enter in lldb, with a prototype of your class methods. For instance, I have a class MyClass which inherits from NSObject, it has two methods of interest, "setArg:" and "getArg" which set and get a float ivar. This is a silly little example, but it shows how to use it. Here's a prefix file I wrote for lldb:
@interface NSObject @end @interface MyClass : NSObject - init; - setArg: (float)arg; - (float) getArg; @end extern "C" { int strcmp (const char *, const char *); int printf(const char * __restrict, ...); void puts (const char *); }
in my ~/.lldbinit
file I add
settings set target.expr-prefix /Users/jason/lldb-prefix.h
and now I can do
(lldb) p [var getArg] (float) $0 = 0.5 (lldb) p [var setArg:0.7] (id) $1 = 0x0000000100104740 (lldb) p [var getArg] (float) $2 = 0.7
You'll notice I included a couple of standard C library functions in here too. After doing this, I don't need to cast the return types of these any more, e.g.
(lldb) p printf("HI\n") <no result> HI (lldb) p strcmp ("HI", "THERE") (int) $3 = -12
(a fix for that "<no result>" thing has been committed to the lldb TOT sources already.)
If you need multiline, use expression
:
expression do { try thing.save() } catch { print(error) } // code will execute now
Blank line to finish and execute the code.
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