Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to call methods or execute code in LLDB debugger?

Tags:

xcode

llvm

lldb

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?

like image 482
Proud Member Avatar asked Oct 10 '12 22:10

Proud Member


People also ask

Is LLDB better than GDB?

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.

Is LLDB the same as GDB?

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.


2 Answers

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.)

like image 110
Jason Molenda Avatar answered Sep 22 '22 06:09

Jason Molenda


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.

like image 22
João Souza Avatar answered Sep 25 '22 06:09

João Souza