Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon

Debugging

Save for later
  • 11 min read
  • 14 Jan 2016

article-image

In this article by Brett Ohland and Jayant Varma, the authors of Xcode 7 Essentials (Second Edition), we learn about the debugging process, as the Grace Hopper had a remarkable career. She not only became a Rear Admiral in the U.S. Navy but also contributed to the field of computer science in many important ways during her lifetime. She was one of the first programmers on an early computer called Mark I during World War II. She invented the first compiler and was the head of a group that created the FLOW-MATIC language, which would later be extended to create the COBOL programming language.

How does this relate to debugging? Well, in 1947, she was leading a team of engineers who were creating the successor of the Mark I computer (called Mark II) when the computer stopped working correctly. The culprit turned out to be a moth that had managed to fly into, and block the operation of, an important relay inside of the computer; she remarked that they had successfully debugged the system and went on to popularize the term. The moth and the log book page that it is attached to are on display in The Smithsonian Museum of American History in Washington D.C.

While physical bugs in your systems are an astronomically rare occurrence, software bugs are extremely common. No developer sets out to write a piece of code that doesn't act as expected and crash, but bugs are inevitable.

Luckily, Xcode has an assortment of tools and utilities to help you become a great detective and exterminator.

In this article, we will cover the following topics:

  • Breakpoints
  • The LLDB console
  • Debugging the view hierarchy
  • Tooltips and a Quick Look

(For more resources related to this topic, see here.)

Breakpoints

The typical development cycle of writing code, compiling, and then running your app on a device or in the simulator doesn't give you much insight into the internal state of the program. Clicking the stop button will, as the name suggests, stop the program and remove it from the memory. If your app crashes, or if you notice that a string is formatted incorrectly or the wrong photo is loaded into a view, you have no idea what code caused the issue. Surely, you could use the print statement in your code to output values on the console, but as your application involves more and more moving parts, this becomes unmanageable. A better option is to create breakpoints.

A breakpoint is simply a point in your source code at which the execution of your program will pause and put your IDE into a debugging mode. While in this mode, you can inspect any objects that are in the memory, see a trace of the program's execution flow, and even step the program into or over instructions in your source code.

Creating a breakpoint is simple. In the standard editor, there is a gutter that is shown to the immediate left of your code. Most often, there are line numbers in this area, and clicking on a line number will add a blue arrow to that line. That is a breakpoint.

If you don't see the line numbers in your gutter, simply open Xcode's settings by going to Xcode | Settings (or pressing the Cmd + , keyboard shortcut) and toggling the line numbers option in the editor section.

Clicking on the breakpoint again will dim the arrow and disable the breakpoint. You can remove the breakpoint completely by clicking, dragging, and releasing the arrow indicator well outside of the gutter. A dust ball animation will let you know that it has been removed.

You can also delete breakpoints by right-clicking on the arrow indicator and selecting Delete.

debugging-img-0The Standard Editor showing a breakpoint on line 14

Listing breakpoints

You can see a list of all active or inactive breakpoints in your app by opening the breakpoint navigator in the sidebar to the left (Cmd + 7). The list will show the file and line number of each breakpoint. Selecting any of them will quickly take the source editor to that location.

debugging-img-1

Using the + icon at the bottom of the sidebar will let you set many more types of advanced breakpoints, such as the Exception, Symbolic, Open GL Errors, and Test Failure breakpoints. More information about these types can be found on Apple's Developer site at https://developer.apple.com.

The debug area

When Xcode reaches a breakpoint, its debugging mode will become active. The debug navigator will appear in the sidebar on the left, and if you've printed any information onto the console, the debug area will automatically appear below the editor area:

debugging-img-2

The buttons in the top bar of the debug area are as follows (from left to right):

  • Hide/Show debug area: Toggles the visibility of the debug area
  • Activate/Deactivate breakpoints: This icon activates or deactivates all breakpoints
  • Step Over: Execute the current line or function and pause at the next line
  • Step Into: This executes the current line and jumps to any functions that are called
  • Step Out: This exits the current function and places you at the line of code that called the current function
  • Debug view hierarchy: This shows you a stacked representation of the view hierarchy
  • Location: Since the simulator doesn't have GPS, you can set its location here (Apple HQ, London, and City Bike Ride are some of them)
  • Stack Frame selector: This lets you choose a frame in which the current breakpoint is running

The main window of the debug area can be split into two panes: the variables view and the LLDB console.

The variables view

The variables view shows all the variables and constants that are in the memory and within the current scope of your code. If the instance is a value type, it will show the value, and if it's an object type, you'll see a memory address, as shown in the following screenshot:

debugging-img-3

This view shows all the variables and constants that are in the memory and within the current scope of your code. If the instance is a value type, it will show the value, and if it's an object type, you'll see a memory address.

For collection types (arrays and dictionaries), you have the ability to drill down to the contents of the collection by toggling the arrow indicator on the left-hand side of each instance.

In the bottom toolbar, there are three sections:

Unlock access to the largest independent learning library in Tech for FREE!
Get unlimited access to 7500+ expert-authored eBooks and video courses covering every tech area you can think of.
Renews at AU $24.99/month. Cancel anytime
  • Scope selector: This let's you toggle between showing the current scope, showing the global scope, or setting it to auto to select for you
  • Information icons: The Quick Look icon will show quick look information in a popup, while the print information button will print the instance's description on the console
  • Filter area: You can filter the list of values using this standard filter input box

The console area

The console area is the area where the system will place all system-generated messages as well as any messages that are printed using the print or NSLog statements. These messages will be displayed only while the application is running.

debugging-img-4

While you are in debug mode, the console area becomes an interactive console in the LLDB debugger. This interactive mode lets you print the values of instances in memory, run debugger commands, inspect code, evaluate code, step through, and even skip code.

As Xcode has matured over the years, more and more of the advanced information available for you in the console has become accessible in the GUI. Two important and useful commands for use within the console are p and po:

  • po: Prints the description of the object
  • p: Prints the value of an object

Depending on the type of variable or constant, p and po may give different information.

As an example, let's take a UITableViewCell that was created in our showcase app, now place a breakpoint in the tableView:cellForRowAtIndexPath method in the ExamleTableView class:

(lldb) p cell

(UITableViewCell) $R0 = 0x7a8f0000 {

  UIView = {

    UIResponder = {

      NSObject = {

        isa = 0x7a8f0000

      }

      _hasAlternateNextResponder = ' '

      _hasInputAssistantItem = ' '

    }

    ... removed 100 lines

 (lldb) po cell

<UITableViewCell: 0x7a8f0000; frame = (0 0; 320 44); text = 'Helium'; clipsToBounds = YES; autoresize = W; layer = <CALayer: 0x7a6a02c0>>

The p has printed out a lot of detail about the object while po has displayed a curated list of information. It's good to know and use each of these commands; each one displays different information.

The debug navigator

To open the debug navigator, you can click on its icon in the navigator sidebar or use the Cmd + 6 keyboard shortcut. This navigator will show data only while you are in debug mode:

debugging-img-5

The navigator has several groups of information:

  • The gauges area: At a glance, this shows information about how your application is using the CPU, Memory, Disk, Network, and iCloud (only when your app is using it) resources. Clicking on each gauge will show more details in the standard editor area.
  • The processes area: This lists all currently active threads and their processes. This is important information for advanced debugging.

The information in the gauges area used to be accessible only if you ran your application in and attached the running process to a separate instruments application. Because of the extra step in running our app in this separate application, Apple started including this information inside of Xcode starting from Xcode 6. This information is invaluable for spotting issues in your application, such as memory leaks, or spotting inefficient code by watching the CPU usage.

debugging-img-6

The preceding screenshot shows the Memory Report screen. Because this is running in the simulator, the amount of RAM available for your application is the amount available on your system. The gauge on the left-hand side shows the current usage as a percentage of the available RAM. The Usage Comparison area shows how much RAM your application is using compared to other processes and the available free space. Finally, the bottom area shows a graph of memory usage over time.

Each of these pieces of information is useful for the debugging of your application for crashes and performance.

Quick Look

There, we were able to see from within the standard editor the contents of variables and constants. While Xcode is in debug mode, we have this very ability. Simply hover the mouse over most instance variables and a Quick Look popup will appear to show you a graphical representation, like this:

debugging-img-7

Quick Look knows how to handle built-in classes, such as CGRect or UIImage, but what about custom classes that you create? Let's say that you create a class representation of an Employee object. What information would be the best way to visualize an instance? You could show the employee's photo, their name, their employee number, and so on. Since the system can't judge what information is important, it will rely on the developer to decide.

The debugQuickLookObject() method can be added to any class, and any object or value that is returned will show up within the Quick Look popup:

func debugQuickLookObject() -> AnyObject {

    return "This is the custom preview text"

}

Suppose we were to add that code to the ViewController class and put a breakpoint on the super.viewDidLoad() line:

import UIKit

class ViewController: UIViewController {

 

    override func viewDidLoad() {

        super.viewDidLoad()

        // Do any additional setup after loading the view, typically from a nib.

    }

 

    override func didReceiveMemoryWarning() {

        super.didReceiveMemoryWarning()

        // Dispose of any resources that can be recreated.

    }

 

    func debugQuickLookObject() -> AnyObject {

        return "I am a quick look value"

    }

 

}

Now, in the variables list in the debug area, you can click on the Quick Look icon, and the following screen will appear:

debugging-img-8

Summary

Debugging is an art as well as a science. Because of this, it easily can—and does—take entire books to cover the subject. The best way to learn techniques and tools is by experimenting on your own code.

Resources for Article:

 


Further resources on this subject: