How To Debug Swift Code with LLDB
This guide contains the following content to ease your journey to become an lldb ninja:
— Object inspection
— Code modification
— Breakpoints manipulation
— Tips and tricks
Object inspection
In this section, we will use “po”, “p” and “v” commands to inspect any suspicious objects in your debugging journey.
(lldb) po
Definition
This very famous command prints an object’s description. It is a compiled expression that has full access to the language so you can execute expressions inside the scope of a breakpoint.
Usage
(lldb) po
And you can print an object child property value using dot notation
(lldb) po <object_name>.child
customizing printed message:
The object should conform to CustomDebugStringConvertible protocol which requires one computed property (get only) called debugDescription and returns String.
extension <type_name>: CustomDebugStringConvertible {
var debugDescription: String {
return "This is custom description for <type_name>"
}
}
(lldb) p
Definition
This is a compiled expression that has full access to the language and output LLDB-formatted description (DataFormatter)
Usage
(lldb) p <object_name>
Dynamic type resolution
This is the process of verifying the type at runtime.
Let’s consider the following example:
protocol CanWalk {
func walk()
}
struct Person: CanWalk {
let name: String
func walk() { ... }
}
let aPerson: CanWalk = Person(name: "John")
Notice in code the static type of aPerson is CanWalk but at runtime the variable will have an instance type of Person , which is its dynamic type?..
p only computes the static type on the result, this is so, because similar to po, it compiles and then executes the code.
(lldb) v
The LLDB debugger has a new command alias ( since Xcode 10.2 ), v, which is an alias for frame variable command to print variables in the current stack frame.
(lldb) v aPerson
will deal with aPerson as an instance of Person which is its dynamic type.
The v command is significantly faster because it doesn’t execute or compile any commands at all.
Customizing lldb DataFormatter
However, in certain cases, you may want to associate a different style to the display for certain data types. To do so, you need to give hints to the debugger as to how variables should be displayed.
The LLDB type command allows you to do just that. Using it you can change your visualization.
The type command has five subcommands:
— type format
— type summary
— type filter
— type synthetic
— type category
Each of the commands (except type category) has four subcommands available:
add: associates a new printing option to one or more types
delete: deletes an existing association
list: provides a listing of all associations
clear: deletes all associations
We are going to focus on type filter and type summary for today’s article.
Filters
Filters are a solution to the display of complex classes. At times, classes have many member variables but not all of these are actually necessary for the user to see.
A filter will solve this issue by only letting the user see those member variables he cares about. Of course, the equivalent of a filter can be implemented easily using synthetic children, but a filter lets you get the job done without having to write Python code.
For instance, if your class Foobar has member variables named A thru Z, but you only need to see the ones named B, H and Q, you can define a filter:
adding filter
(lldb) type filter add Foobar --child B --child H --child Q
(lldb) v aFoobarObject
will print only variables B, H and Q
If you need to delete a custom filter simply type type filter delete followed by the name of the type to which the filter applies. To delete ALL filters, use type filter clear. To see all the filters defined, use type filter list.
String summaries
type summary works by extracting information from classes and structures, and arranging it in a user-defined format.
adding summary
(lldb) type summary add Foobar --summary-string "has one property called A and its value is ${var.A}"
(lldb) v aFoobarObject
will print:
(Foobar) aFoobarObject = "has one property called A and its value is 15"
Code modification
In this section we will use an expression command to make changes to your code only inside the debugging session.
(lldb) expression
This allows you to execute arbitrary code in the debugger.
Usage
(lldb) expression isThisreal = false
Breakpoints manipulation
In this section you'll learn how to create, modify, and delete breakpoints.
Create
(lldb) breakpoint set
This command deletes all breakpoints.
Usage
(lldb) breakpoint set -n "-[NSView hitTest:]" -C "po $rdi" -G1
this command says to create a breakpoint on -[NSView hitTest:], have it execute the "po $rdi" command which instructs LLDB to print out the contents of the object at the memory address referenced by what’s stored in the RDI assembly register., then automatically continue after executing the command.
The following registers are used as parameters when a function is called in x64 assembly. Try and commit these to memory, as you’ll use these frequently in the future:
— First Argument: RDI
— Second Argument: RSI
— Third Argument: RDX
— Fourth Argument: RCX
— Fifth Argument: R8
— Sixth Argument: R9
-G0: says to the breakpoint to not automatically resume execution after the action has been performed
-G1: says to the breakpoint to automatically resume execution after the action has been performed.
(lldb) breakpoint set --one-shot true --name "-[NSView hitTest:]"
this command says to create a one shot breakpoint on -[NSView hitTest:] will be deleted automatically.
Modify
(lldb) breakpoint modify
This command modifies existing breakpoints.
Usage
(lldb) breakpoint modify -c '(BOOL)[NSStringFromClass((id)[$rdi class])
containsString:@"IDESourceEditorView"]' -G0
This command modifies all existing breakpoints in your debugging session and creates a condition which gets evaluated every time -[NSView hitTest:] fires. If the condition evaluates to true, then execution will pause in the debugger. This condition checks that the instance of the NSView is of type IDESourceEditorView. The final -G0 says to modify the breakpoint to not automatically resume execution after the action has been performed.
Delete
(lldb) breakpoint delete
This command deletes all breakpoints.
Usage
(lldb) breakpoint delete
Tips and tricks
This section contains some tips and tricks I'd like to use to enhance my debugging workflow.
(lldb) continue
This command will resume execution.
Usage
(lldb) continue
or c for short
(lldb) c
assembly registers
I do forget this assembly registers all the time but fortunately there is a way to not use them.
(lldb) po $arg1
arg1 -> rdi
arg2 -> rsi
arg3 -> rdx
arg4 -> rcx
arg5 -> r8
arg6 -> r9
There is a special case for arg2 which represents the selector, because lldb doesn't know the type of the arguments you need to explicitly typecast it.
(lldb) po (SEL)$arg2
Replacing code
I can't count how many times I needed to replace a line of code and put another.
(lldb) thread jump --by 1
This will skip one line.
(lldb) expression isThisreal = false
New tab for Debug
This is very useful feature in Xcode, you can make xcode create new tab for debug automatically
goto xcode menu >> preferences >> behaviors >> Pauses >> check Show tab named [Debug] in [Active window]
UI manipulation
— Get the memory address for this view.
(lldb) expression -l objc -o -- [`self.view` recursiveDescription]
— Use view's memory address to modify its properties.
(lldb) expression -l objc -o -- 0x7fb3afc40e90
there is another way to do this
(lldb) po unsafeBitCast(, to: <type_name>.self)
now you can modify any property
(lldb) po unsafeBitCast(, to: <type_name>.self).center.y = 300
— Finally update the screen's frame buffer
(lldb) expression CATransaction.flush()
Aliases
This is very useful to shortening long commands, po in objective c is a very good example.
(lldb) command alias poc expression -l objc -o --
And now, I can do this:
(lldb) poc 0x7fb3afc40e90
More info
Related posts
The latest articles from Andela.

How to hire a Python developer: A guide to finding the right fit

Top takeaways from Gartner IT Symposium
.png)
Android ML face detection with Camera X
We have a 96%+
talent match success rate.
The Andela Talent Operating Platform provides transparency to talent profiles and assessment before hiring. AI-driven algorithms match the right talent for the job.
