Everything you need to know about debugging in iOS — Part 1

Ankit Chaudhary
Sep 9, 2018 · 7 min read

Debugging plays a crucial role in the lifecycle of an app development — how many times do we find ourselves stuck in a situation and the debugging mode has always been a savior for us — and that’s why the main objective of this article is to understand it properly. Plain debugging is a straightforward process where we can add breakpoints and debug things accordingly but here we are going to dig down deep to understand what makes those process running.

Rather than wasting more time, let’s move on to the agenda of this article -

  • Specialised Breakpoint ( Conditional Breakpoint )
  • Expression
  • Skipping / Injecting code while Debugging
  • Making use of Debug description
  • Creating Alias and making use of a memory address
  • Watchpoint

Specialised Breakpoint / Conditional Breakpoint

Yeah, that’s what I call them “Special”. This is the most favorite feature of mine and it works well in the adverse situation. Editing Breakpoint is as easy as double tapping on the breakpoint and confirming the condition and expression you need to run upon.
So let’s take an example -

Consider a scenario where we are going to iterate a range varying from 0 to 100 and if we want to jump on to the condition where the value is 89 then we have to press the continue button 88 times and that’s when conditional breakpoint comes into play. We can directly define the condition to activate the breakpoint, provided the condition expression values matches. Obviously, this is not a very advanced feature but a must to know.

For example, I created a nested loop with dependent variables i, j and created an edit breakpoint condition which only gets active when the condition meets.

Expression or (e)

Expression is used to evaluate the statement you type in debugger hence making it a very powerful tool to explore and modify variable’s values. Various commands that you might have used in Xcode debugger are an alias of an “expression” command.

For instance, the “po” command that we use while debugging into objects is nothing other than an alias of expression which is -

`expression — object-description — <expression>`

Similarly “p” is also one of the commands which you might have used and the only difference from “po” is that it reads the value from memory. “p” expression somewhat looks like this -

`expression — <expression>`

Expression syntax notation looks like this -

(lldb) expression <flags> — <variable>

Expression syntax notation looks like this -

(lldb) expression <flags> — <variable>

To distinct flags and expression statement lldb uses double dash notation ` — ` after expression command.

There are around 25+ flags available that can help you to execute with the different set of command options.

Flags that most times have come in useful to me are as follows -

* -A ( — show-all-children )
Ignore the upper bound on the number of children to show.

* -O ( — object-description )
Display using a language-specific description API, if possible.

* -T ( — show-types )
Show variable types when dumping values.

  • -a <boolean> ( — all-threads <boolean> )
    Should we run all threads if the execution doesn’t complete on one thread.

The last one -Z comes in useful when your expression is dependent on more than one thread and you want to execute the statement on all threads for the completion.

There are other command options available that you can explore using lldb prompt by typing “help expression”.

Injecting and Skipping Code while Debugging

After completing a functionality most of the time we find ourselves identifying a bug, understanding the cause, making changes and recompiling the build which almost consumes most of our day. To make this process easier we can use some technique while debugging and recompiling code so that we can buy ourselves some time without getting into the tandem of building over and over again.

To inject set of code we can edit breakpoint and add actions onto it which will execute before the line we added it on and make changes. In order to understand it well, we will take an example where there are persons which are assigned to different grade pay according to the position but we can see there are some bugs that we need to fix and get rid of them
in one shot

Image 1

Bugs that need to be fixed

  • Data is not coming proper, as there’re only three employee details showing up whereas we have created four.
  • Another error is to fix grade pay of employee two whose grade-pay is coming in groupC whereas we need to change it to groupB.

Solution

In order to fix these two errors without recompiling code, we need to add an expression and append the empFour to array created and jump over the thread by 1. Further on, set empTwo grade pay to group B.

Here we have used both techniques where we changed the existing data by injecting code via breakpoint edit functionality and jumped over a line of code so that we can skip that part.

Making use of Debug description

When debugging into objects, we sometimes don’t get any information and just get a printed name and memory address but what if we need more (info of that object), this is where debug expression comes into play which predefines what set of information will be printed when you use “po” command on it.

Here we are using a person object and creating employee object out of it but when we are trying to print those in debugger we get a value something like this -

So, in order to fix this, we need to extend our class to CustomStringConvertible protocol that will provide us with a variable where we are open to print the information according to our opinion. Here, we have added a description variable to confirm the CustomStringConvertible protocol.

From now on whenever you try to debug the object you’ll get a descriptive print statement rather than a vague address of an object.

Creating Alias and making use of the memory address

As discussed above, many of the commands that we use in the daily debugging process are derived from other commands like *po* which is an alias of *expression*.

Similarly, we can also create our own alias but before heading to that we need to learn a few more things i.e how can we make use of a memory address. The memory address is somewhat an unknown language but would n’t it be great if we start decoding that info into a meaningful one.

This is something that can be achieved by “expression” command.

(lldb) expression -l objc -O — 0x7fef0550f120
<DebuggingPartOne.ViewController: 0x7fef0550f120>

But, here we can do something better by turning this expression into an alias. In order to create an alias, we use alias command prepended with “command” command and further on add the statement that you want to use as an alias. For the above problem, the alias expression will go like this -

command alias pmod expression -l objc -O

So, now we can directly use this -

pmod 0x7fef0550f120

Watchpoints

Watchpoints are a tool you can use to monitor the value of a variable or memory address for changes and trigger a pause in the debugger when changes happen. They can be very helpful in identifying problems with the state of your program that you might not know precisely how to track down.

Consider the previous example in which we have added an assignedCount variable whose value gets increased every time assigned pay button gets pressed. In order to watch the assigned count, we add a watchpoint on assigned count variable and whenever any changes made to this variable memory address a pause in the debugger will happen.

Adding a watchpoint is as easy as selecting the variable from the bottom left pane and clicking left option and select watch “assignedCount”.

From here onwards whenever any change has been made the debugger will trigger a pause as shown in the image -

We just need to check the debug trace and go back by 1 step and we’ll see the point from where the change gets executed.

Conclusion

In this post, I have barely scratched the surface of debugging. In the next post, we will be looking into lldb commands in the reference which will enable us to do most of the task using lldb command prompt.

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade