Magic bullets for lldb debugger on iOS.

Radoslaw Cieciwa
2 min readJul 23, 2016

--

This article will show you few magic tricks that you can use while you debug iOS apps. I discovered them in articles, exploration of our app and talking to apple engineer about one bug that i described here.

Let’s start!

Assigning Obj-C or Swift expression into python variables

(lldb) expression id $application = (UIApplication *)[UIApplication sharedApplication]

Really cool trick if you want to dig more into your app. It helps explore your object graph. Later on you just use it like:

(lldb) po [$application delegate]
<AppDelegate: 0x7feb82c0f600>

You can use either objc or swift expressions here.

Trap your app in any runtime moment of your app to get access to your object graph.

Just tap this button on your xCode bottom toolbar (under text editor).

xCode bottom toolbar

And here you can just jump to UIApplicationDelegate (aka. AppDelegate) and from there to your keyWindow.

(lldb) expression id $delegate = (id)[[UIApplication sharedApplication] delegate]
(lldb) expression id $keyWindow= (id)[$delegate window]
(lldb) expression id $root = (id)[$keyWindow rootViewController]
(lldb) po $root
<UITabBarController: 0x7facaada2c80>

Catch a frame for more detailed inspection

If you tried — after making a trap (pause button on xCode) — to print a back trace or a frame.

(lldb) breakpoint set -f GroupOperation.swift --line 53
Breakpoint 3: where = Brainly`Brainly.GroupOperation.execute () -> () + 12 at GroupOperation.swift:53, address = 0x000000010c8a4b8c
(lldb) expression -i false —- (void)[$go execute]
error: Execution was interrupted, reason: breakpoint 3.1.
(lldb) frame variable self -D 1
(Brainly.GroupOperation) self = 0x00007fca7a68ae30 {
Brainly.Operation ={…}
internalQueue = 0x00007fca7a6895f0{…}
startingOperation = 0x00007fca7a68ac40{…}
finishingOperation = 0x00007fca7a68b040{…}
aggregatedErrors = 0 values{…}
}

-i stands for — don’t ignore the breakpoints

after double hyphen (--) you specify function to invoke, remember to set return type

Now we catch a function call stack. If you continue from this breakpoint you will return to previous state — which is the trap. Another example for UIKit class:

(lldb) breakpoint set -S isViewLoaded
Breakpoint 4: where = UIKit`-[UIViewController isViewLoaded], address = 0x000000010187d485
(lldb) expression -i false — (BOOL)[$rootV isViewLoaded]
error: Execution was interrupted, reason: breakpoint 4.1.

Assign variable by address

You can assign variables if you only have the address of the object. After setting id as a type it will deduce proper type. Just look at the example:

(lldb) expression id $tabBar = (id)0x7facaada2c80
(lldb) po $tabBar
<UITabBarController: 0x7facaada2c80>

If you have yours lldb trick, just let me now in comments or just message me Radoslaw Cieciwa.

--

--

Radoslaw Cieciwa

Father, passionate Instagrammer, sportsman and a very crafty iOS Developer