Advanced Lldb Tricks for Swift — Injecting and Changing Code on the Fly

Advanced Lldb Tricks for Swift — Injecting and Changing Code on the Fly

While Xcode provides several visual abstractions for lldb commands like adding breakpoints by clicking the lines of code and running by clicking the play button, lldb provides several useful commands that are not present in Xcode’s UI.

While Xcode provides several visual abstractions for lldb commands like adding breakpoints by clicking the lines of code and running by clicking the play button, lldb provides several useful commands that are not present in Xcode’s UI. This can range from creating methods on the fly to even changing the CPU’s registers to force a specific flow on the app without having to recompile it, and knowing them can greatly improve your debugging experience.

Not all Swift things are developed in Xcode — things like the Swift Compiler or Apple’s SourceKit-LSP work better through other means, and these means usually end up having you use lldb manually. Without Xcode to assist you, some of these tricks can prevent you from having to compile the app again to test certain changes.

Note: If you find code hard to read on Medium, check out this post in my blog SwiftRocks!

Injecting properties and methods

You might already know po (short for "print object") -- the friendly command that is commonly used to print the contents of a property:

func foo() {
    var myProperty = 0
} // a breakpoint

However, po is much more powerful than that -- despite the name implying that it prints things, po is an alias for expression --object-description --, an argumented version of the more raw expression (or just e) command that makes the output more swifty:

po myProperty
0

Because it’s an alias, po can do everything that e can. e is meant for evaluating expressions, which can range from printing properties to changing their values and even defining new classes. As a simple use, we can change the value of a property in the code to force a new flow without recompiling the code:

Besides that, if you write po alone, you'll be able to write a multiline expression like this. We can use this to create completely new methods and classes inside our debugging session:

po
Enter expressions, then terminate with an empty line to evaluate:
1 class $BreakpointUtils {
2     static var $counter = 0
3 }
4 func $increaseCounter() {
5     $BreakpointUtils.$counter += 1
6     print("Times I've hit this breakpoint: \($BreakpointUtils.$counter)")
7 }
8

(Dollar signs are used here to indicate that these properties and methods belong to lldb, and not the actual code.)

The previous example allows me to call $increaseCounter() directly from lldb, which will add 1 to my "I can't handle this bug anymore" counter.

po $increaseCounter()
Times I've hit this breakpoint: 1
po $increaseCounter()
Times I've hit this breakpoint: 2

The ability to do this can be combined with lldb’s ability to import plugins, which can considerably enhance your debugging experience. A good example of this is Chisel, a tool made by Facebook that contains lots of lldb plugins — like the border command, which adds a bright border to an UIView so you can quickly locate it on the screen, and they all work through clever usages of epo.

xcode swift-programming programming swift ios

Bootstrap 5 Complete Course with Examples

Bootstrap 5 Tutorial - Bootstrap 5 Crash Course for Beginners

Nest.JS Tutorial for Beginners

Hello Vue 3: A First Look at Vue 3 and the Composition API

Building a simple Applications with Vue 3

Deno Crash Course: Explore Deno and Create a full REST API with Deno

How to Build a Real-time Chat App with Deno and WebSockets

Convert HTML to Markdown Online

HTML entity encoder decoder Online

The ultimate guide to iOS Unit Testing with Swift and Xcode

Unit testing is a testing method where you can test “unit” of code whether it is working as you want or not. In Xcode, use XCTest…

HOW TO BUILD CUSTOM ALERT DIALOG BOX FROM SCRATCH STEP BY STEP USING SWIFT iOS XCODE 11.4

Topic: HOW TO BUILD CUSTOM ALERT DIALOG BOX FROM SCRATCH STEP BY STEP USING SWIFT iOS XCODE 11.4 Subscribe Us: http://bit.ly/2UaSC5s Find us on: Discord: htt...

New in iOS 14: App Attest

When jailbreaking of iOS devices first became popular, it was common for iOS developers to try to defend their apps from users that altered their devices to enable piracy.

Debugging on iOS 14 With Xcode 11

Fixing a critical bug when you are between app (and Xcode) versions ... the dmg instead... you'll thank me later :) // Support iOS 14 devices (Xcode 12.0) with Xcode 11.5: ... Looks like Xcode 11 changes the game here, this no longer works. ... Anyone got the iphone running iOS 13.2 to debug on Xcode 10.1 yet?

10 Free Online Resources To Learn Swift Language

Swift is a fast and efficient general-purpose programming language that provides real-time feedback and can be seamlessly incorporated.