The basic function of a debugger is to explore and modify variables’ values. This is what expression or e is made for (and much more actually). You can evaluate basically any expression or command in a runtime.

Let’s assume you’re debugging some function valueOfLifeWithoutSumOf() which do a summation of two numbers and extract the result from 42.

Let’s also assume you keep getting the wrong answer and you don’t know why. So to find a problem you can do something like this:

Or… it’s better to use LLDB expression instead to change the value in the runtime. And find out where the problem has happened. First, set a breakpoint to a place you interested in. Then run your app.

To print the value of specific variable in LLDB format you should call:

(lldb) e <variable>

And the very same command is used to evaluate some expression:

(lldb) e <expression>

(lldb) e sum

(Int) $R0 = 6 // You can also use $R0 to refer to this variable in the future (during current debug session) (lldb) e sum = 4 // Change value of sum variable (lldb) e sum

(Int) $R2 = 4 // sum variable will be "4" till the end of debugging session

expression command also has some flags. To distinct flags and actual expression LLDB uses double-dash notation -- after expression command like this:

(lldb) expression <some flags> -- <variable>

expression has almost ~30 different flags. And I encourage you to explore them all. Write the command below in the terminal to get full documentation:

> lldb

> (lldb) help # To explore all available commands

> (lldb) help expression # To explore all expressions related sub-commands

I’d like to stop on the following expression 's flags:

-D <count> ( --depth <count> ) — Set the max recurse depth when dumping aggregate types (default is infinity).

( ) — Set the max recurse depth when dumping aggregate types (default is infinity). -O ( --object-description ) — Display using a language-specific description API, if possible.

( ) — Display using a language-specific description API, if possible. -T ( --show-types ) — Show variable types when dumping values.

( ) — Show variable types when dumping values. -f <format> ( --format <format> ) –– Specify a format to be used for display.

( ) –– Specify a format to be used for display. -i <boolean> ( --ignore-breakpoints <boolean> ) — Ignore breakpoint hits while running expressions

Let’s say we have some object called logger . This object contains some string and structure as properties. For example, you want to explore first-level properties only. Just use -D flag with appropriate depth level to do so:

(lldb) e -D 1 -- logger (LLDB_Debugger_Exploration.Logger) $R5 = 0x0000608000087e90 {

currentClassName = "ViewController"

debuggerStruct ={...}

}

By default LLDB will look infinitely into the object and show you a full description of every nested object:

(lldb) e -- logger (LLDB_Debugger_Exploration.Logger) $R6 = 0x0000608000087e90 {

currentClassName = "ViewController"

debuggerStruct = (methodName = "name", lineNumber = 2, commandCounter = 23)

}

You can also explore object description with e -O -- or simply using alias po like in the example below:

(lldb) po logger <Logger: 0x608000087e90>