Debugging Chronicles: Exploring Breakpoints, Conditions, LLDB Commands, and Watchpoints
When it comes to creating a product, the business layer is as crucial as the design. Now that we’ve seen how to debug view components, we can talk about debugging anything, especially the business logic.
Using Playground files
In most projects, there certainly needs to be some helper functions. If those functions are buggy, your app or a feature of your app will not work as expected. So, I recommend debugging/testing your helper functions, especially the ones that include complex business logic.
You can simply add playground file into your project. All you need to do is to insert a new file from menu bar: File-> New-> Playground
Please keep in mind that if the playground file and the models called inside are in the same module, it won’t be a problem. Otherwise, you need to give public access level to your models in order to use them.
Use of Breakpoints
As a developer, I can’t imagine implementing complex features or fixing bugs without breakpoints. A breakpoint is a debugging tool that allows you to pause the execution of your program at a certain moment. Breakpoints in Xcode are essential tools for effectively debugging code.
Just click on the bottom area adjacent to the code line you wish to pause in order to establish a breakpoint. Run your application in debug mode after setting the breakpoint, and it will stop when it reaches it. From there, you can rapidly identify and address problems in your code by using Xcode’s debugging features, which include the debug console, variable inspection, and step-through execution. Breakpoints are customizable and can be turned on and off to meet your debugging requirements.
Use of LLDB Commands
During debugging sessions, Xcode’s LLDB (Low-Level Debugger) debugger offers an extensive command set for examining and modifying the state of your program in addition to allowing you to set breakpoints.
LLDB commands are somehow related to breakpoints, as you cannot run an LLDB command in the terminal without first placing a breakpoint.
Inspecting Your Code: Essential LLDB Commands to Examine
p Command
p
(print), a basic LLDB command, lets you print a variable’s value in the debug console. For instance, entering p
url will cause the url variable to print its current value.
po Command
Another command similar to p
is po
. The po
command will similarly print your object with all of its properties to the console.
e Command
The e
command represents expression and is used for analyzing it. It is capable of executing any code in the current environment of the currently selected frame. This means you may use functions, assign values, and carry out other operations the way you would if you generated code in your source files.
Use LLDB Commands for Modification on Run Time
Actually, the fundamental goal of utilizing the LLDB command for modification is to leave things unaltered.
p Command for Modification
The p command allows you to edit variables and run code within the context of the current debugging session. Here’s how you can edit variables with the p command:
I absolutely haven’t made any changes in the implementation. Just ran p command for modification and I can see the difference on the screen afterwards.
e Command for Modification
You can use e
command and test a function during runtime without making any changes in the implementation as follows.
After running the command, the variable changed successfully. I wasn’t supposed to change anything inside the testButton() function.
As a conclusion, LLDB’s ability to modify variables in real-time enables dynamic adjustments to the behavior of your program, which can be especially useful when fine-tuning algorithms or experimenting with different configurations. By altering variables directly in the debugger, you can iterate more rapidly on your debugging process, refining your understanding of the problem and testing potential solutions iteratively.
Conditional Breakpoints
With Xcode’s advanced debugging capability, you may interrupt program execution only when specific criteria are satisfied by using a conditional breakpoint. This makes it easier to find and repair flaws in your code, especially when you want to look at issues that arise under particular conditions.
To set a conditional breakpoint, open the breakpoint inspector. Right-click on the blue breakpoint indicator. Select Edit Breakpoint from the context menu. This will open the Breakpoint Inspector.
I have used this functionality to ensure that the pull functionality works as expected. The record count is initially 20, and to understand that pagination works, the record count must be greater than 20. I preferred to log a message in that case.
Let’s be more compelling and edit this breakpoint to pause after ignoring 2 attempts. In this way, I am testing if I get at least 80 records after pagination.
Well, that functions as expected. As you can see, I verified that my pagination works as expected by using the conditional breakpoint. It is your call to use it in any way you need.
Obviously, it doesn’t only provide logging functionality. You can also run some debugger commands depending on a condition. In the screenshot below, when my search functionality runs, I have searched for ‘Morty’ when the user entered an empty string.
Add a WatchPoint
Instead of stopping the program’s execution when a line of code is encountered, watchpoints function similarly to breakpoints. Instead, when a particular variable’s value changes, they suspend the program. In situations where you are uncertain about the location or timing of a variable’s value alteration within your code, this capability becomes extremely handy.
In order to add a watchpoint to a variable, we need to add a breakpoint at first.
I simply right-click on the variable that I want to watch. I continue execution, and the execution pauses whenever the watched variable changes. This allows me to inspect the new value and see exactly where in the code the change has occurred.
Thank you for joining me on this deep dive into the world of debugging with breakpoints, conditions, LLDB commands, and watchpoints. Mastering these tools and techniques is crucial for efficient and effective software development. I hope this exploration has provided you with valuable insights and practical tips to enhance your debugging skills. Remember, debugging is an art, and the more you practice, the more proficient you’ll become. Happy debugging, and until next time, keep solving those challenging bugs with confidence and precision!