Xcode Debugging
Xcode Debugging
IDEs
2009-10-19
Simultaneously published in the United States
Apple Inc. and Canada.
© 2009 Apple Inc. Even though Apple has reviewed this document,
All rights reserved. APPLE MAKES NO WARRANTY OR REPRESENTATION,
EITHER EXPRESS OR IMPLIED, WITH RESPECT TO
THIS DOCUMENT, ITS QUALITY, ACCURACY,
No part of this publication may be reproduced, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR
PURPOSE. AS A RESULT, THIS DOCUMENT IS
stored in a retrieval system, or transmitted, in PROVIDED “AS IS,” AND YOU, THE READER, ARE
any form or by any means, mechanical, ASSUMING THE ENTIRE RISK AS TO ITS QUALITY
electronic, photocopying, recording, or AND ACCURACY.
otherwise, without prior written permission of IN NO EVENT WILL APPLE BE LIABLE FOR DIRECT,
INDIRECT, SPECIAL, INCIDENTAL, OR
Apple Inc., with the following exceptions: Any CONSEQUENTIAL DAMAGES RESULTING FROM ANY
person is hereby authorized to store DEFECT OR INACCURACY IN THIS DOCUMENT, even
if advised of the possibility of such damages.
documentation on a single computer for
personal use only and to print copies of THE WARRANTY AND REMEDIES SET FORTH ABOVE
ARE EXCLUSIVE AND IN LIEU OF ALL OTHERS, ORAL
documentation for personal use provided that OR WRITTEN, EXPRESS OR IMPLIED. No Apple
the documentation contains Apple’s copyright dealer, agent, or employee is authorized to make
any modification, extension, or addition to this
notice. warranty.
The Apple logo is a trademark of Apple Inc. Some states do not allow the exclusion or limitation
of implied warranties or liability for incidental or
Use of the “keyboard” Apple logo consequential damages, so the above limitation or
exclusion may not apply to you. This warranty gives
(Option-Shift-K) for commercial purposes you specific legal rights, and you may also have
without the prior written consent of Apple may other rights which vary from state to state.
constitute trademark infringement and unfair
competition in violation of federal and state
laws.
No licenses, express or implied, are granted
with respect to any of the technology described
in this document. Apple retains all intellectual
property rights associated with the technology
described in this document. This document is
intended to assist application developers to
develop applications only for Apple-labeled
computers.
Every effort has been made to ensure that the
information in this document is accurate. Apple
is not responsible for typographical errors.
Apple Inc.
1 Infinite Loop
Cupertino, CA 95014
408-996-1010
Introduction Introduction 7
Debugging Environments 9
Debugging Workflow 9
Building a Product with Debugging Symbols 10
The Debugger 11
Troubleshooting Debugger Display 12
Viewing Threads and Stack Frames in the Debugger 13
Viewing Variables in the Debugger 13
Viewing Global Variables 14
Viewing Disassembly Code and Processor Registers 16
Using Breakpoints 29
Managing Breakpoints 29
3
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
CONTENTS
Index 69
4
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
Figures, Tables, and Listings
5
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
FIGURES, TABLES, AND LISTINGS
6
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
INTRODUCTION
Introduction
Finding and eliminating bugs in your code is a critical phase of the development process. Xcode provides
advanced debugging facilities, which include debugging from the text editor so that you don’t stray far from
your code, and using the mini debugger, which provides a graphical debugging experience that is less
intrusive on the running application than other methods. You can also use a more traditional, specialized
graphical debugger, or the debugger console.
This document describes the Xcode debugging environments and explains how to trace your program’s
execution and view its data. It is intended for developers and system administrators who want to use Xcode
to debug programs and analyze their behavior and performance.
Prerequisites: To get the most out of this document, you should be familiar with the basic development
features Xcode provides. See Xcode Workspace Guide and Xcode Project Management Guide to learn about
basic Xcode usage.
Software requirements: This document is written for Xcode 3.2 and later.
The first chapter, "Debugging Essentials" (page 9), provides a high-level summary of the Xcode debugging
environments.
The next five chapters describe the debugging environments and show how to customize your debugging
experience:
■ "Debugging in the Debugger" (page 11) describes the main debugging environment.
■ "Debugging in the Text Editor" (page 17) describes the text-editor–based debugging environment.
■ "Debugging in the Mini Debugger" (page 23) explains how to use the mini debugger to debug programs
unobtrusively.
■ "Debugging in the Console" (page 25) discusses the GDB Console window.
■ "Debugging Preferences" (page 27) describes the Debugging preferences pane.
■ "Managing Program Execution" (page 29) describes the mechanisms used to control and monitor the
execution of programs.
■ "Viewing Variables and Memory" (page 39) discusses the various ways in which you can view the values
of variables as you debug your programs.
■ "Modifying Running Code" (page 53) shows how you can modify your executable while it is running.
■ "Debugging Programs Remotely" (page 59) describes how to debug a program running on another
computer.
■ "Mac OS X Low-Level Debugging" (page 63) describes the Mac OS X debugging facilities that can help
you in your debugging tasks.
■ "Debug Information Format" (page 65) talks about the storage and usage of debug information in
binaries.
Debugging Essentials
Xcode lets you analyze your code line by line to view your program’s state at a particular stage of execution.
This process is called debugging. To debug a program, you run it under the control of a debugger, which
lets you pause programs and examine their state.
Debugging Environments
■ In the text editor. The text editor allows you to perform many debugging operations, such as stepping
through code lines and viewing the contents of variables. Debugging in the text editor lets you be close
to your code as you debug it.
■ In the mini debugger. The mini debugger is a floating window that lets you perform debugging
operations in way that is less intrusive to your code than debugging within Xcode. The mini debugger
lets you debug your application in an environment that closely resembles the way your customers use
your application.
■ In the debugger. The Xcode graphical debugger provides a rich, traditional debugging experience.
■ In the console. Some debugging operations produce textual output, which is displayed in the console.
This window can also be used to issue commands directly to the GDB (The GNU Project Debugger)
instead of through the Xcode graphical debugger.
Debugging Workflow
When you debug a product, Xcode opens a debugging session with a debugger and your product’s binary.
Before you can debug a program, however, it should contain as much debugging information as possible,
so that Xcode can provide you with accurate and useful information during your debugging. See “Building
for Debugging” in Xcode Project Management Guide for information about how to build a program to debug.
You may also debug a running process (not launched by Xcode). This operation is known as attaching to a
process. You can attach to a program running under Xcode or to any process for which you have a process
ID. To attach to a running program use Run > Attach to Process.
This menu lists currently running programs launched from Xcode, identified by the program name and the
name of the corresponding Xcode project. (This menu also lists other programs running on the computer.)
You can use the menu’s Process ID option to attach to any process using its process ID, which you obtain
using UNIX utilities such as top.
Debugging Environments 9
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
CHAPTER 1
Debugging Essentials
Note: When you launch a program from Xcode, you can also have Xcode automatically attempt to attach
to the process when the program crashes. See "Executable-Environment Debugging Information" in Xcode
Project Management Guide for details.
Before you can take advantage of the source-level debugger, the compiler must collect debugging information.
To generate debugging symbols for a product, turn on the Generate Debug Symbols (see
“GCC_GENERATE_DEBUGGING_SYMBOLS (Generate Debug Symbols)” in Xcode Build Setting Reference) build
setting and build the product. This setting is turned on by default in the Debug build configuration. If you
use this build configuration as the active build configuration when you build your target, the compiler
generates the necessary debugging information. For more information about build configurations, see Build
Configurations.
To view the build settings that are set in the Debug build configuration:
1. In the project window, select the target or targets you want to build and bring up the target editor.
3. Choose Debug (or Development) from the Configuration pop-up menu at the top of the pane. You
should see the Generate Debug Symbols setting in the table of build settings. Make sure that this setting
is turned on; if it is, a checkmark appears in the Value column for this setting. Otherwise, turn on the
setting by clicking the checkbox in the Value column.
Important: When building your product using a build system other than Xcode, you must ensure that
lazy-symbol loading is turned off. See "Debugging Preferences" (page 27) for more information.
For more information about building and running programs, see Xcode Project Management Guide.
The Xcode Debugger window offers a traditional but rich debugging experience. This chapter describes the
debugger and explains how to use its features to debug your program.
The Debugger
Toolbar
Variable list
Thread list
Text editor
Status bar
■ Toolbar
Contains items used to manage your project and to control your program’s execution.
■ Thread list
Displays the call stack of the current thread. The pop-up menu above this view lets you select different
threads to view when debugging a multi-threaded application.
■ Variable list
The Debugger 11
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
CHAPTER 2
Debugging in the Debugger
Shows the variables defined in the current scope and their values. This section also shows the current
state of all processor registers when the disassembly view is enabled (see "Viewing Disassembly Code
and Processor Registers" (page 16) for more information).
■ Text editor
This pane displays the source code you are debugging. When execution of your program is paused, the
debugger indicates the line at which execution is paused by displaying the PC indicator, which appears
as a red arrow. The line of code is also highlighted. You can change the color used to highlight the
currently executing statement with the Instruction Pointer Highlight color well in Xcode > Preferences
> Debugging.
The text editor pane offers alternate ways to execute debugging commands. See "Gutter Shortcut
Menu" (page 18) and "Debugger Datatips" (page 19) for details.
■ Status bar
Displays the current status of the debugging session. For example, in the window shown above, Xcode
indicates that GDB has just finished loading symbols for a single shared library.
You can change the layout of the Debugger window by choosing one of the following options:
The Debugger Display menu also lets you specify whether to show source code and/or disassembly code.
See "Viewing Disassembly Code and Processor Registers" (page 16) to learn more about viewing disassembly
code.
■ Make sure you have the source. Apple’s frameworks and many third-party libraries don’t include source
code
■ Make sure the product contains debugging information. See “Building for Debugging” in Xcode Project
Management Guide and “Executable-Environment Debugging Information” in Xcode Project Management
Guide.
■ If the file is in the Groups & Files list, make sure its name is not in red (red means Xcode can’t find the
file).
■ If the file is not in the Groups & Files list and your target may need to process it, add the file to the project.
See Files in Projects.
■ If the file is for a library or framework that was built for you, do one of the following:
❏ Place the source file in the same location used by the person who built the library or framework.
When someone builds a debuggable binary, the compiler stores the paths of its source files in the
binary.
❏ Add the directory that contains the file to the source directories list:
1. Open the executable environment Info window.
12 The Debugger
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
CHAPTER 2
Debugging in the Debugger
3. Enter the directory’s pathname in the “Additional directories to find source files in” list.
For each function or method call that your program makes, the debugger stores information about it in a
stack frame. These stack frames are stored in the call stack. When execution of your program is paused in
the debugger, Xcode displays the call stack for the currently running process in the Thread list and puts the
most recent call at the top.
In multithreaded programs, you can switch between the call stack of each thread using the Thread pop-up
menu described in "The Debugger" (page 11) or with these commands:
Selecting any function call in the call stack displays the stack frame for that function. The stack frame includes
information on the arguments to the function, variables defined in the function, and the location of the
function call. Xcode displays the frame’s variables in the Variable list and displays its currently executing
statement in the text editor with the process counter (PC)—a red arrow. If a stack frame is dimmed, no source
code is available for it.
To learn about viewing the stack frame in the text editor, see "Debugger Strip" (page 18).
The variables view (Figure 2-2) shows information—such as name, type and value—about the variables in
your program. Variables are displayed for the stack frame that is currently selected in the Debugger window.
2. The Type column displays the type of the variable. This column is optional. To display it, choose Debug
> Variables View > Show Types.
3. The Value column shows the contents of the variable. If a variable’s value is in red, it changed when the
application was last active. You can edit the value of any variable; the changed value is used when you
resume execution of your program.
4. The Summary column gives more information on the contents of a variable. It can be a description of
the variable or an English language summary of the variable’s value. For example, if a variable represents
a point, its summary could read “(x = x value, y = y value).” You can edit the summary of a variable by
double-clicking the Summary column or choosing Debug > Variables View > Edit Summary Format. For
a description of how you can format variable summaries, see "Using Data Formatters" (page 39).
Xcode provides predefined data formatters for several data types, including unichar, wchar_t, and
any UTF-16 type.
You can choose which columns the debugger shows in the Variable view; Xcode remembers these columns
across debugging sessions.
Variables in the Variable view are grouped by category, as shown in Figure 2-2. To view variables in any of
these groups, click the disclosure triangle next to that group. These groups are:
■ The Arguments group contains the arguments to the function that is currently selected in the call stack.
■ The Locals group contains the local variables declared in the function that is currently selected in the
call stack.
■ The Globals group shows global variables and their values. By default, there are no global variables in
this section; you must select those variables you want to track in the Globals Browser, described in
"Viewing Global Variables" (page 14).
■ The File Statics group shows file statics, if any. This group is not shown if none are present.
To view or inspect the contents of a structured variable (including arrays and vectors) or an object, click the
disclosure triangle beside the variable’s name. You can also use a data formatter to display a variable’s
contents in the Summary column, as described in "Using Data Formatters" (page 39), or you can view a
variable in its own window. Viewing a variable in its own window is particularly useful for viewing the contents
of complex structured variables. To open a variable in its own window, double-click the variable’s name or
select it and choose Debug > Variables View > View Variable in Window.
To learn how to view variables in the text editor, see "Debugger Datatips" (page 19).
To open the Globals Browser, choose Run > Show > Global Variables.
The debugger must be running and execution of the program being debugged must be paused for this item
to be available. If you attempt to open of the Globals group when it’s empty, Xcode automatically opens the
Globals Browser.
The Library list, on the left side of the Globals Browser, lists the available libraries, including system libraries
and your own libraries.
Important: To view the global variables declared in the libraries your program uses, the program must load
all the symbols declared in each library. To learn how to configure your program to load all its dependent
libraries’ symbols, see "Viewing Shared Libraries" (page 50).
To see a library’s global variables, select that library in the list; the global variables defined by that library are
shown in the table to the right. In the globals table, you can see:
You can use the search field at the top of the Globals Browser window to filter the contents of the global
variables table. To the right of the search field, Xcode displays the number of global variables currently visible,
as a fraction of the total number of global variables in the currently selected library.
To add a global variable to the Globals list in the Debugger window variable view, select the checkbox in
the View column next to the global variable.
When you select a library in the Library list, the full path to that library is displayed below the list.
When you choose to display disassembly code or when no source code is available for the function or method
selected in the Thread list, Xcode displays a pane with disassembled code in the debugger. Figure 2-4 shows
disassembled code in the debugger after choosing to view source and disassembly code using the Run >
Debugger Display menu.
When the disassembly pane is shown, the Variable list contains a Registers group containing all the processor
registers.
You can perform many debugging tasks in the text editor, including controlling program flow, managing
breakpoints and watchpoints, and viewing program memory. See The Text Editor to learn more about the
text editor’s capabilities.
This chapter describes how to debug your program from the text editor.
“Text Editor Debugger Controls” shows the text editor and the debugging controls it provides.
Debugger strip
Gutter
Debugger datatip
Debugger Strip
The debugger strip (Figure 3-2) is a small control strip that appears above the content pane. It lets you
perform several debugging tasks.
Thread list
Breakpoints Debugger
Continue Console Call list
Step out
Step in
Step over
The text editor gutter includes several shortcuts to debugging facilities. The code line indicated by the pointer
at the time you choose the shortcut is the action line. These include:
18 Debugger Strip
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
CHAPTER 3
Debugging in the Text Editor
Debugger Datatips
As you debug your program in the text editor, you may need to analyze the contents of the program’s
variables as you step through code lines. You can view your program’s variables using a debugger datatip.
When the pointer hovers over a variable, its contents are progressively disclosed using disclosure triangles.
You can also modify the contents of mutable variables.
Figure 3-3 shows a debugger datatip showing the contents of the bounds variable. In addition to viewing
the variable’s value, you can also modify that value. After double-clicking the value of the height field of
the size structure, you can change it to another value before executing the code line that uses the bounds
variable.
Figure 3-3 Changing variables with debugger datatips in the text editor
As you move the pointer over a disclosure triangle in a datatip row, the contents of the field the row represents
are disclosed below that row. (You can turn off this behavior, as explained later.) When the pointer hovers
to the right of the disclosure triangle, a control with two small triangles appears. Clicking that control shows
the datatip menu. The datatip menu provides the following commands.
■ Print Description: Prints the description of the current datatip field in the console.
■ Open in Window: Opens a window containing the data of the current datatip field.
■ View as Memory: Shows the contents of the current datatip field in the memory viewer window. See
"Browsing Memory" (page 48) for more information.
■ Jump to Definition: Opens the file that declares the data type of the current datatip field.
■ Jump to Documentation: Opens the reference for the data type of the current datatip field.
Debugger Datatips 19
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
CHAPTER 3
Debugging in the Text Editor
■ Show Types: Toggles the display of the data type of the datatip fields.
■ Show Data Formatters: Toggles the display of data formatters for the datatip fields.
■ Sort by Name: Sorts datatip fields by field name.
■ Sort by Type: Sorts datatip fields by field data type.
■ No Sort: Applies no sorting to datatip fields.
■ Auto Expand: Toggles the autoexpansion of datatip fields that represent structures when the pointer
hovers over the corresponding disclosure triangle.
Debugger datatips also provide program-flow–control controls called step controls. These controls allow you
to perform Continue, Step Into, and Step Over commands from the content pane of the text editor. To turn
on step controls, chose Run > Debugger Display > Datatips > Step Controls.
■ Continue to Here
To perform this command, let the pointer hover over the gutter identifying the action line. The Continue
to Here icon appears on the left margin of the line (Figure 3-4). Clicking this icon continues program
execution up to the action line.
20 Debugger Datatips
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
CHAPTER 3
Debugging in the Text Editor
Debugger Datatips 21
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
CHAPTER 3
Debugging in the Text Editor
22 Debugger Datatips
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
CHAPTER 4
The mini debugger is a floating window that provides debugging controls similar to those of the text editor
(see "Debugging in the Text Editor" (page 17)) and the debugger (see "Debugging in the Debugger" (page
11)), but that don’t require your switching back and forth between your application and Xcode.
The mini debugger has two modes, depending on whether the debugged process is running or stopped.
When the process is running, the mini debugger provides controls to pause and stop the process, display
the program’s Xcode project, and activate or deactivate breakpoints. When the program is stopped (after
reaching a breakpoint, for example), the mini debugger provides a debugging experience similar to the one
provided by the text editor. In fact, when the your program is stopped, the mini debugger’s entire content
is made up of a text editor, although you cannot edit the source files it displays.
To show the mini debugger while running your application, choose Run > Mini Debugger.
Stop Breakpoints
Pause Project
You can tell Xcode to always open the mini debugger when you debug a product using the On Start menu
in Xcode Preferences > Debugging. See “Debugging Preferences” in Xcode Workspace Guide for more
information.
These are the icons the mini debugger shows when the program is running:
Figure 4-2 shows the mini debugger after the program stops.
For more information about debugging in the mini debugger, see "Debugging in the Text Editor" (page 17).
Keep in mind that the text editor in the mini debugger doesn’t allow you to edit source files.
Xcode’s graphical interface for GDB, the GNU debugger, lets you perform most necessary debugging tasks.
You may, however, encounter situations—such as working with watchpoints in GDB—that require you to
interact directly with the debugger on the command line. Using the console window, you can:
■ View the commands that Xcode sends to GDB or the Java command-line debugger
■ Send commands directly to GDB or the Java command-line debugger (limited support)
■ View the debugger output for those commands
■ See debugging messages printed to stderr by your program or by system frameworks
■ Debug a command-line program that requires input from stdin
If you are debugging a command-line program that requires input from stdin, you must use the console
to communicate with your program when it is running in the debugger. This window is only available when
your program is running under the debugger.
Note: Support for working with the Java debugger is very limited. You should consider using Eclipse for
Java development. Visit http://www.eclipse.org for more information.
To enter commands, click in the console window and type at the gdb or JavaBug prompt. To get help with
GDB and Java debugging commands, enter help at the console. To learn more about command-line
debugging with GDB, see Debugging with GDB.
Note: To have the gdb or JavaBug prompt in the console, the program you’re debugging must be paused.
To make the Console text easily readable, Xcode lets you choose the text colors and fonts used in the console
window. You can use different fonts and colors for the text you type in the console, the text the debugger
writes to the console, and the debug console’s prompt. To change the colors used for text in the console
window, use the Fonts and Colors group in Xcode > Preferences > Debugging. See “Debugging Preferences”
in Xcode Workspace Guide for more information.
Note that Xcode uses an executable environment to determine how to launch your program. To specify
command-line arguments and environment variables to use when launching your program from Xcode, edit
the executable environment; you cannot alter this environment from the gdb command-line in the console
window. See “Configuring Executable Environments” in Xcode Project Management Guide to learn more about
configuring an executable environment.
Debugging Preferences
The Debugging pane of Xcode preferences contains options for customizing the debugger console, the text
editor debugging experience, and other debugging aspects. Figure 6-1 shows the Debugging preferences
pane.
■ Fonts and Colors: Specifies the color and font used for text in the console.
■ Instruction Pointer Highlight: Specifies the color used to highlight the location of the instruction pointer
in the debugger window when execution of the current program is stopped.
■ On Start: Specifies actions to perform when you launch a program from Xcode. The actions include
showing the console, the debugger, or the mini debugger.
■ GDB Log: Specifies a file into which GDB logs its activities.
■ Symbol Loading Options: Specifies symbol loading behavior.
27
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
CHAPTER 6
Debugging Preferences
❏ Load symbols lazily: When selected, the debugger defers loading symbols until they are needed.
Otherwise, Xcode loads all symbols for the executable and its libraries when you launch it in the
debugger. You can further customize which symbols are loaded in the Shared Libraries window.
See "Viewing Shared Libraries" (page 50) for more information.
■ Disassembly Style: Specifies the disassembly format used in the text editor and the debugger. See
"Viewing Disassembly Code and Processor Registers" (page 16) for more information.
■ In-Editor Debugger Controls: Specifies whether the debugger strip appears in the text editor. See
"Debugger Strip" (page 18) to learn about the debugger strip.
■ Auto Clear Debug Console. Specifies whether to clear the debugging console at the start of a debugging
session.
28
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
CHAPTER 7
Xcode provides several mechanisms to control and monitor the execution of an inferior (a program being
debugged). While debugging a program you can:
■ Pause execution as a result of an event; you may also perform actions such as logging and emitting
sounds
■ Monitor the value of variables or data items
■ Pause execution through special Core Services debugging functions
This section describes the facilities Xcode provides to let you control and monitor the execution of your
program.
Using Breakpoints
Breakpoints let you perform actions on certain events, such as when program execution reaches a certain
point in the code. Table 7-1 lists the three types of breakpoints.
You can add one or more breakpoint actions to a breakpoint. A breakpoint action is an operation that Xcode
performs when the breakpoint is triggered. The default action (when the breakpoint has no breakpoint action
associated to it) is to pause program execution. However, Xcode also supports:
Managing Breakpoints
The following sections show how to view, add, activate/deactivate, customize, and remove breakpoints.
Using Breakpoints 29
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
CHAPTER 7
Managing Program Execution
Viewing Breakpoints
The breakpoints window lets you view and modify breakpoints set in the current project, as well as any
defined for the current user. To open the breakpoints window, choose Run > Show > Breakpoints.
Breakpoints are collected in the Breakpoints smart group. This smart group contains two subgroups: the
Project Breakpoints group, which contains breakpoints specific to the current project, and the Global
Breakpoints group, which contains breakpoints defined for the current user. Project breakpoints are stored
in the project’s user file; that is, they are saved for the current user and the current project. Global breakpoints
are available to you in any project that you open.
You can select the Project Breakpoints group or the Global Breakpoints group to see only those breakpoints
in the detail view; you can also open the group to see its contents in the outline view. Selecting the Breakpoints
smart group displays all available breakpoints in the detail view.
■ The disclosure triangle shows and hides any actions associated with the breakpoint.
■ The icon indicates the type of the breakpoint. A file icon indicates that it is a file-line or C++ exception
breakpoint. A blue cube indicates that it is a symbolic breakpoint.
■ The Breakpoint column displays the title of the breakpoint. For file-line breakpoints, it displays the line
number and surrounding context of the location at which the breakpoint is set. For symbolic breakpoints,
it displays the name of the function or method on which the breakpoint is set.
■ The column with the checkmark indicates whether the breakpoint is turned on (selected) or off
(unselected). When a breakpoint is turned on (and breakpoints are active), program execution stops
when it reaches the specified line or routine call. Otherwise, program execution does not stop on it.
A dash in this checkbox indicates that, while the breakpoint is turned on, the debugger has not yet
resolved it. When you start debugging, these dashes change to checkmarks as the debugger resolves
each breakpoint.
■ The Location column shows the file in which file line breakpoints are located. For symbolic breakpoints,
this column displays “Symbol.”
30 Using Breakpoints
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
CHAPTER 7
Managing Program Execution
■ The Condition column lets you specify an execute condition for the breakpoint. When you specify a
condition, the breakpoint is triggered only if the condition (for example, i == 24) is true. You can use
any variables that are in the current scope for that breakpoint. Note that you must cast any function calls
to the appropriate return type.
■ The Ignore Count column specifies the number of times program execution goes through the breakpoint
before the the breakpoint is triggered. For example, setting the ignore count for a breakpoint to 5 makes
your program stop the sixth time the breakpoint is hit.
■ The column with the Continue symbol indicates whether to automatically continue execution of your
program after hitting the breakpoint. If the checkbox in this column is selected, program execution stops
on the breakpoint, Xcode performs any breakpoint actions and then automatically resumes execution
of the program. Otherwise, program execution stops on the breakpoint, Xcode performs any breakpoint
actions, and your program does not resume until you give Xcode the command to continue.
You can delete, and turn off or on any existing breakpoint in your project in the breakpoints window. You
can also create symbolic breakpoints. However, you can add a breakpoint to a specific line of code only from
the editor or the console.
To view the source code for a breakpoint, double-click the breakpoint in the breakpoints window. The source
file in which the breakpoint is set (or the function is defined) opens in a separate editor window.
■ Select the line at which you want the breakpoint to be triggered and choose Run > Manage Breakpoints
> Add Breakpoint at Current Line.
■ Use the gutter shortcut (contextual) menu. See "Gutter Shortcut Menu" (page 18) for details.
You can easily move a file-line breakpoint from one code line to another line by dragging the breakpoint
arrow to the new line within the code editor.
■ Select the trigger code line and choose Run > Manage Breakpoints > Add Symbolic Breakpoint. In the
dialog that appears, enter the name of the method or function at which you want the breakpoint to be
triggered.
■ Open the breakpoints window, double-click on “Double-Click for Symbol,” and enter the trigger routine
name.
Using Breakpoints 31
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
CHAPTER 7
Managing Program Execution
Note: When you set a breakpoint on an Objective-C method, you must include the brackets and a plus or
minus sign. For example, to stop whenever a Cocoa exception is raised, enter -[NSException raise].
The @synthesize directive instructs the compiler to create accessor methods for a property declared with
the @property directive. During a debugging session, you may need to set breakpoints on a class’s accessor
methods; for example, to find out the places in the program that modify a particular variable. To do that,
you can use symbolic breakpoints, as described in "Adding Symbolic Breakpoints" (page 31).
A more convenient way of setting breakpoints on synthesized accessors is to set the breakpoint on the code
line with the @synthesize directive. If the program is being debugged, (or the next time you start a
debugging session on it), Xcode asks you to identify the methods to which you want to add a breakpoint,
as shown in Figure 7-2. Xcode remembers your selections in subsequent debugging sessions.
32 Using Breakpoints
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
CHAPTER 7
Managing Program Execution
Note: If you rename a property with synthesized accessors that has a breakpoint set on its @synthesize
directive, Xcode discards the breakpoint selections made under the old name. If you leave the breakpoint at
the @synthesize code line, you have to make your breakpoint selections again.
To add an Objective-C exception breakpoint, select Stop on Objective-C Exceptions under the Run >
Activate/Deactivate menu, as shown in Figure 7-3.
To add a C++ exception breakpoint, select the trigger code line and choose Run > Manage Breakpoints >
Add C++ Exception Breakpoint. In the dialog that appears, enter the name of the trigger exception.
Xcode allows you to import and export breakpoints. This feature lets you share sets of breakpoints with other
developers working on the same project, or across projects.
To export breakpoints, select the breakpoints you want to export from the Breakpoints smart group in the
Groups & Files list and choose Run > Manage Breakpoints > Export Breakpoints.
To import breakpoints into a project, open the Breakpoints smart group and select the group to which you
want to add the breakpoints—either Project Breakpoints or Global Breakpoints and choose, Run > Manage
Breakpoints > Import Breakpoints.
Xcode adds a new subgroup containing the imported breakpoints to the selected breakpoints group.
Grouping Breakpoints
To group existing breakpoints, select them in the Breakpoints smart group and choose Group from the Groups
& Files shortcut menu.
You can create your own groups within the Breakpoints smart group to organize breakpoints. To add a
breakpoints group:
Using Breakpoints 33
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
CHAPTER 7
Managing Program Execution
1. Select either the Project Breakpoints or the Global Breakpoints group, depending on which breakpoint
realm you want to operate on.
Removing Breakpoints
You can remove breakpoints using the text editor of the breakpoints window.
To remove a fine-line breakpoint, open the breakpoint’s file in the text editor and drag the breakpoint indicator
out of the gutter. You may also select the code line with the breakpoint and choose Run > Manage Breakpoints
> Remove Breakpoint at Current Line.
To remove symbolic and C++ exception breakpoints, open the breakpoints window, select the breakpoint,
and press Delete.
In the course of debugging a program, you may find that you don’t currently want the debugger to use a
particular breakpoint that you have set, but you don’t want to delete it entirely, either, in case you want to
use it again at a later time. Instead of deleting the breakpoint from your project, you can simply turn it off.
Breakpoints that are turned off are not triggered during program execution.
You can turn any breakpoint in your project on or off. Simply open the breakpoints window and click the
checkbox beside the breakpoint you want to modify. A breakpoint is turned on when this checkbox is selected.
You can also turn file-line breakpoints on or off from the text editor by clicking the breakpoint in the gutter.
Breakpoints that are turned off appear as a light-gray arrow in the gutter.
You can turn more than one breakpoint on or off—or even groups of breakpoints—at once. To do so:
1. Select the breakpoints you want to turn on or off in the Breakpoints smart group in the Groups & Files
list. You can select the individual breakpoints or a breakpoint group.
2. Choose Enable Breakpoints or Disable Breakpoints from the gutter shortcut menu.
To quickly turn on a set of breakpoints, disabling any other breakpoints for the project, select the breakpoints
you want to turn on and choose Enable Only These Breakpoints from the gutter Option shortcut menu
(Control-Option-click). Turning a breakpoints group on or off affects all breakpoints in that group and in all
its subgroups.
Xcode provides a number of breakpoint templates that you can use to insert file-line breakpoints that are
preconfigured with various breakpoint actions. To add a breakpoint based on one of these templates, in the
text editor’s gutter, choose Built in Breakpoints from the shortcut menu.
34 Using Breakpoints
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
CHAPTER 7
Managing Program Execution
■ Log breakpoint with arguments and auto-continue. Creates a breakpoint that prints the arguments
of the currently executing function or method to the console and automatically continues.
■ Log breakpoint and hit count and auto-continue. Creates a breakpoint that prints the number of times
the breakpoint has been hit during the current debugging session to the console and automatically
continues.
■ Log stack trace and auto-continue. Creates a breakpoint that prints a backtrace of the entire stack for
the current thread and automatically continues. The Debugger Command action uses the GDB command
bt to generate the backtrace.
■ Sound out and auto-continue. Creates a breakpoint that uses the Sound action to play an alert and
automatically continues.
■ Print self and auto-continue. Creates a breakpoint that prints a description of an Objective-C object
and automatically continues.
■ Speak breakpoint and hit count and auto-continue. This creates a breakpoint that uses the Log action
to speak the breakpoint name and the number of times it has been encountered during the current
debugging session and then automatically continues.
When you choose one of these templates, Xcode inserts a breakpoint at the current line of code and configures
it with the appropriate action. You can edit the breakpoint action in the breakpoints window.
You can create your own breakpoint templates from any breakpoints that you have configured by placing
them in a group called Template Breakpoints. Any breakpoints that you add to this group appear in the
Built-in Breakpoints gutter shortcut menu.
Conditionalizing Breakpoints
To have the debugger execute breakpoint actions only under certain circumstances, you can associate an
execute or ignore condition with a file-line or symbolic breakpoint. See "Viewing Breakpoints" (page 30) to
learn more about these conditions.
Each time it encounters the breakpoint, the debugger evaluates the expression. If the expression is true—that
is, if it evaluates to a nonzero value—the debugger stops at the breakpoint and Xcode performs any breakpoint
actions. Breakpoint conditions are currently supported only when using GDB.
To associate a breakpoint action with a breakpoint, open the breakpoint in the breakpoints window. This
displays the interface for specifying breakpoint actions, as shown in Figure 7-4.
Using Breakpoints 35
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
CHAPTER 7
Managing Program Execution
To add an action, click the plus (+) button. Choose the type of action you want Xcode to perform from the
actions pop-up menu. Each action has a different interface for specifying the message to log, the sound to
play, and so forth.
■ Debugger Command. Xcode sends a command to the debugger. Type the command in the text field
below the action menu. For example, if you are using GDB, you could specify a command such as
backtrace.
Do not use the GDB commands jump or continue in a breakpoint action if you have set that breakpoint
to automatically continue. If the first action associated with a breakpoint is a Debugger Command action,
Xcode sets the command on the breakpoint using the GDB command commands instead of pausing
execution and then sending the command to GDB.
■ Log. Xcode logs a message when it encounters the breakpoint. You can choose to have Xcode print a
message to the console, speak the message using Text-to-Speech, or do both. Choose either Log or
Speak to specify how Xcode logs the message.
To specify the message that Xcode logs, type it into the text field below the action menu. You can include
information about the current breakpoint in the message using the following formatters:
❏ %B. The name of the breakpoint, as shown in the Breakpoint column of the Breakpoints window. By
default, this is the name of the function or method in which the breakpoint is set, including the line
number for file-line breakpoints. You can also specify your own name for the breakpoint, as described
in "Viewing Breakpoints" (page 30).
❏ %H. The number of times the debugger has encountered the breakpoint in the current debugging
session.
❏ %C. Any comment associated with the breakpoint, as shown in the Comments column of the
Breakpoints window.
For example, if you specify the message Stopped at %B again. We've been here %H times.
Don't you want to stop somewhere else instead?, you would see a message similar to the
following in the console:
Stopped at TDialView::Draw() - Line 305 again. We've been here 5 times. Don't
you want to stop somewhere else instead?
■ Sound. Xcode plays a sound when it encounters the breakpoint. Use the second pop-up menu to specify
which sound to play. You can choose any of the built-in system sounds.
■ Shell Command. Xcode executes a command in your default shell when it encounters the breakpoint.
Enter the name of the command or shell script file in the first text field. You can also click Choose to
navigate to it in the Open dialog. Type any arguments to pass to the command in the second text field.
Xcode displays a warning in the project window status bar when it cannot find the command or shell
script file entered in the first text field.
36 Using Breakpoints
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
CHAPTER 7
Managing Program Execution
If you have set the breakpoint to automatically continue, Xcode does not, by default, wait until the shell
command has finished executing before resuming execution of the program being debugged. To ensure
that Xcode does not continue until the specified command has finished executing, select the “Wait until
done” option.
Xcode prints the exit value the command or shell script in the debugger console, whether “Wait until
done” is selected.
■ AppleScript. Xcode executes an AppleScript script when the breakpoint is encountered. Enter the script
in the text field below the action menu. To compile your script, click the Compile button.
You can use the same format specifiers in your AppleScript script to access information about the current
breakpoint as for the Log action, described above.
Xcode supports these breakpoint actions for GDB, the Java debugger, and the AppleScript debugger. Note,
however, that the debugger commands that you can pass to the Java and AppleScript debuggers using a
debugger command action are limited.
You can use the value of GDB expressions in some breakpoint actions. These expressions can return the value
of a local variable or the result of a function call. The breakpoint actions on which you can use GDB expressions
are Log, Shell Command, and AppleScript. To execute a GDB expression in a breakpoint action, surround the
expression with @ characters. For example, to print the value of the local variable i, use a Log action with
the text i = @i@. To print the name of the running program, use a Log action with the text Program name
is @(char*)getprogname()@.
Using Watchpoints
To monitor changes to the value of variables or data items, you can set watchpoints. A watchpoint pauses
execution of the program whenever the value of the watched item changes. You can set a watchpoint on a
variable only when execution of the program is halted. To set a watchpoint on a variable:
1. With execution of the program paused at a breakpoint, select the variable in the Variable list in the
Debugger window. See "Debugging in the Debugger" (page 11) to learn more about the Variable list.
Xcode displays a magnifying glass next to the variable to indicate that the variable is being watched, as
shown in Figure 7-5.
Using Watchpoints 37
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
CHAPTER 7
Managing Program Execution
When the value of the variable changes, Xcode pauses execution of the program and displays a dialog
showing the location of the program counter and the new value of the variable. If execution of the program
moves beyond the scope of the current variable, Xcode deletes the watchpoint and pauses execution of the
program.
Important: Watching local variables, located on the stack, can cause your program to crash if system calls
are made in the current function.
The Core Services framework includes functions, such as Debugger and DebugStr, that break into the
debugger with a message. If your code contains calls to these functions, you can tell the Xcode debugger to
stop when it encounters them.
You can turn on this feature for an individual executable, as described in “Executable-Environment Debugging
Information” in Xcode Project Management Guide, or for all executables in the current project. To toggle this
feature on or off, choose Run > Stop on Debugger()/DebugStr().
Note: Xcode implements this feature by setting the USERBREAK environment variable to 1, which causes
these functions to send a SIGINT signal to the current process, breaking into the debugger.
This chapter describes the various ways in which you can view the values of variables as you debug your
programs.
You can view the value of a variable in a variety of formats, including hexadecimal, octal, and unsigned
decimal. To display the value of a variable in a different numeric format:
1. Open the Debugger window and select the variable in the Variable list.
Natural
Hexadecimal
OSType
Decimal
Unsigned Decimal
Octal
Binary
You can also cast a variable to a type that’s not included in the menu. For example, a variable may be declared
as void *, yet you know it contains a char * value. To cast a variable to a type, select the variable, choose
Run > Variables View > View Value As.
Xcode allows you to customize how variables are displayed in debugger datatips and the Variable list in the
debugger by specifying your own format strings for the Value or Summary columns. In this way, you can
display program data in a readable format. Xcode includes a number of built-in data formatters for data types
defined by various Mac OS X system frameworks. You can edit these format strings or create your own data
formatters.
To turn data formatters on or off, choose Run > Variables View > Enable Data Formatters.
Data formatters can contain literal text and references to certain values and expressions.
■ Literal text. You can add explanatory text or labels to identify the data presented by the format string.
■ References to values within a structured data type. You can access any member of a structured variable
from the format string for that variable. The syntax for doing so is %<pathToValue>%, where
<pathToValue> is the period-delimited path to the value you want to access in the current data structure.
In C++, to access a member defined in the superclass of an object, the path to the member must include
the name of the superclass. For example, %Superclass.x%. You don’t need to include the public,
protected, and private, keywords in the path.
■ Expressions, including function or method calls. The syntax for an expression is {<expression>}. To
reference the variable itself in <expression>, use $VAR. For example, to display the name of a
notification—of type NSNotification—you can use {(NSString *)[$VAR name]}:s. See "Data
Formatter Macros" (page 40) to learn how to access dynamic structures in data formatters.
■ References to columns in the Variable list. When Xcode resolves a data formatter, it replaces the member
reference or expression with the value that was obtained by evaluating the reference or expression. This
value is the same value found in the Value column of the Variable list. You can, however, specify that
Xcode use the contents of any column in the Variable list—Variable name, Type, Value, or Summary. To
do so, add :<referencedColumn> after the expression or member reference, where
<referencedColumn> is a letter indicating which Variable-list column to access. So, the syntax for
accessing a value in a structured data type becomes %<pathToValue>%:<referencedColumn>. Table
8-1 shows the possible values for referencing variable display columns.
Table 8-1 Characters for referencing variable display columns
v Value
t Type
s Summary
These are the macros through which you can access dynamic structures in data formatters:
This macro is useful only when values of a particular type are always contained in a structure of a specific
type, and information contained in this structure is required to successfully evaluate the target variable.
These are some tips and important concepts to keep in mind when using data formatters in your projects:
■ Threaded code. If you are debugging heavily threaded code and more than one thread is executing the
same code, data formatters may cause threads to run at the wrong time and miss breakpoints. To avoid
this problem, disable data formatters.
■ Double-quotation marks. Double quotation-mark characters in data formatters must be escaped, as in
the following example:
{(NSString *)[$VAR valueForKey:@\"name\"]}:s
■ Memory management. Xcode automatically allocates and deallocates the memory data formatters use.
But if a data formatter returns a reference to data that resides elsewhere, the formatter is responsible
for managing that memory.
Because there’s no mechanism to notify data formatters when they are no longer used, data formatters
should not return dynamically allocated memory. They can, however, return static strings; for example,
"invalid value".
■ C++ data. Your data formatters may take C++ pointers but not C++ references. With references, copies
of the referenced objects are generated, which may cause undesired side effects.
struct CGRect { CGPoint origin; CGSize size; }; typedef struct CGRect CGRect;
Assuming that the goal is to create a format string that displays the origin and size of variables of type
CGRect, there are many ways you can write such a format string. For example, you can reference members
of the origin and size fields directly. Of course, each of these two fields also contains data structures, so
simply referencing the values of those fields isn’t very interesting; the values you want are in the data structures
themselves. One way you can access those values is to include the full path to the desired field from the
CGRect type. For example, to access the height and width of the rectangle, in the height and width fields
of the CGSize structure in the size field you could use the references %size.height% and %size.width%.
A sample format string using these references might be similar to the following:
You could write a similar reference to access the x and y coordinates of the origin. Or, if you already have a
data formatter for values of type CGPoint that displays the x and y coordinates of the point in the Summary
column of the Variable list—such as (%x%, %y%)—you can leverage that format string to display the contents
of the origin field in the data formatter for the CGRect type. You can do so by referencing the Summary
column for CGPoint, as in the following format string:
origin: %origin%:s
When Xcode evaluates this format string, it accesses the origin field and retrieves the contents of the
Summary column for the CGPoint data type, substituting it for the reference to the origin field. The end
result is equivalent to writing the format string origin: (%origin.x%, %origin.y%).
You can combine this format string with the format string for the size field and create a data format string
for the CGRect type similar to the following:
For example, a rectangle with the origin (1,2 ), a width of 3, and a height of 4 results in the following display:
You can also write a data formatter to display the same information using an expression such as the following:
When Xcode evaluates this expression for a variable, it replaces $VAR with a reference to the variable itself.
Of course, using an expression to perform a simple value reference is not necessary. Another example of an
expression in a format string is {(NSString *)[$VAR name]}:s to display the name of a notification, of
type NSNotification.
When you specify a custom data formatter for a variable of a given type, that format string is also used for
all other variables of the same type. Note, however, that you cannot specify a custom format for string types,
such as NSString, char*, and so on. Custom data formatters that you enter in the debugger are stored at:
~/
Library/
Application Support/
Developer/
Shared/
Xcode/
CustomDataViews/
CustomDataViews.plist
A data-formatter bundle is a plug-in that contains functions you can invoke from the data formatters
described in "Using Data Formatters" (page 39). You use data-formatter bundles when you need more power
to create a textual representation of a variable than data-formatter expressions provide.
■ CustomDataViews.plist file. Defines the front-end (the text representation) of the data formatter.
Data-formatter bundles and the data-formatter function they define must meet these requirements:
■ Data-formatter functions must return char * for their output to be displayed in the Summary column
of the debugger Variables list.
■ Data-formatter bundles must be installed in the <Xcode> directory.
3. Delete the External Frameworks and Libraries group from the TemperatureFormatter group in the Groups
& Files list.
1. Add the Temperature.h header file, which defines the Temperature data type.
// Temperature.h
typedef struct {
int degrees;
char scale;
} Temperature;
2. Add the Temperature_formatter.c file, which implements the Temperature data formatter. (This
implementation file doesn’t require a corresponding header file.)
// Temperature_formatter.c
// Change /Developer with the path to your <Xcode> directory if you've placed it
elsewhere.
#import
"/Developer/Applications/Xcode.app/Contents/PlugIns/GDBMIDebugging.xcplugin/Contents/Headers/DataFormatterPlugin.h"
#include <stdlib.h>
#include <string.h>
#include "Temperature.h"
// Error message.
static char *nullPluginFunctions = "CFDataFormatter plugin error: _pbxgdb_plugin_functions
not set!";
// Debugging aid.
printf("format_Temperature(identifier: %i)\n", identifier);
return formatter_buff;
}
3. Add a property list file named CustomDataViews.plist. Enter the following properties to the file:
4. Set the Installation Build Products Location target build setting for all configurations to:
$(DEVELOPER_DIR)
5. Set the Installation Directory target build setting for all configurations to:
/Library/Xcode/CustomDataViews
6. Delete the Fix & Continue target build setting for all configurations.
7. Build the bundle, and ensure that there are no build errors.
> cd <TemperatureFormatter_project_directory>
> /Developer/usr/bin/xcodebuild install -target TemperatureFormatter
9. Restart Xcode.
The following steps test the bundle created in "Create the TemperatureFormatter Data-Formatter Bundle" (page
44).
// TemperatureFormatter_test_main.c
#include <stdlib.h>
#include "Temperature.h"
7. Verify that the Variable list in the debugger displays the formatted data, as shown in Figure 8-1.
Using the Expressions window, you can view and track the value of an expression. For example, you can track
a global value or a function result over the course of a debugging session.
To open the Expressions window, choose Run > Show > Expressions.
Type the expression you want to track in the Expression field. Xcode adds the expression, evaluates it, and
displays the value and summary for that expression. The display format of the value and summary information
is determined by any data formatters in effect.
The expression can include any variables that are in scope at the current statement and can use any function
in your project. To view processor registers, enter an expression such as '$r0', '$r1'.
In the debugger you can add a variable to the Expressions window by selecting the variable in the Variable
list and choosing Run > Variables View > View Variable As Expression.
To remove an expression from the Expressions window, select it and press Delete.
■ The expression is evaluated in the current frame. As the frame changes, the expression may go in and
out of scope. When an expression goes out of scope, Xcode notes this in the Summary column.
■ Always cast a function to its proper return type. The debugger doesn’t know the return type for many
functions. For example, use (int)getpid() instead of getpid().
■ Expressions and functions can have side effects. For example, i++ increments i each time it’s evaluated.
If you step though 10 lines of code, i is incremented 10 times.
Browsing Memory
When execution of the current program is paused, you can browse the contents of memory using a memory
browser.
To open a memory browser, like the one shown in Figure 8-2, choose Run > Show > Memory Browsers.
48 Browsing Memory
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
CHAPTER 8
Viewing Variables and Memory
You can also open a memory browser to the location of a particular variable:
Browsing Memory 49
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
CHAPTER 8
Viewing Variables and Memory
■ The Word Size pop-up menu specifies the size of the memory chunks you want to view. For example,
to analyze memory you know contains 32-bit integers, you would choose 4 from the menu.
Note: On a big-endian system, the word size that you choose affects the spacing of the data displayed
by the Memory Browser. On a little-endian system, however, the word size can also affect the byte order.
If you are debugging on Intel-based computers, make sure you choose an appropriate word size for
viewing memory. In most cases, the appropriate word size is 1.
■ The Columns pop-up menu specifies the number of columns the browser uses to display the identified
memory.
■ The New Memory Browser button opens another memory browser. You can use multiple memory browser
to compare the contents of different sections of memory.
You can see which libraries have been loaded by the program using the Shared Libraries window, shown in
Figure 8-3. To open this window, choose Run > Show > Shared Libraries.
The Module Information table lists all the individual libraries the executable links against. In this table, you
can see the name and address of each shared library, as well as the symbols the debugger has loaded for
that library. The Starting Level column shows which symbols the debugger loads by default for a given library
when the current executable is running. The Current Level column shows which symbols the debugger has
loaded for the library during the current debugging session. When an entry has a value in the Address and
Current Level columns, the library has been loaded in the debugging session.
The path at the bottom of the window shows where the currently selected library is located in the file system.
You can quickly locate a particular library by using the search field to filter the list of libraries by name.
Using the Shared Libraries window you can also choose which symbols the debugger loads for a shared
library. This can help the debugger load your project faster. You can specify a default symbol level for all
system and user libraries; you can also change which symbols the debugger loads for individual libraries.
For any shared library, you can choose one of three levels of debugging information:
■ All: Loads all debugging information, including all symbol names and the line numbers for your source
code.
■ External: Loads only the names of the symbols declared external.
■ None: Loads no information.
You can specify a different symbol level for system libraries and user libraries. User libraries are any libraries
produced by a target in the current project. System libraries are all other libraries.
By default, the debugger loads only external symbols for system and user libraries, and automatically loads
additional symbols as needed. Turning off the “Load symbols lazily” option, described in "Debugging
Preferences" (page 27), changes the default symbol level for User Libraries to All. This is a per-user setting
and affects all executables you define. You can also customize the default symbol level settings for system
and user libraries on a per-executable basis, using the Default Level pop-up menus in the Shared Libraries
window.
For some special cases—applications with a large number of symbols—you may want to customize the
default symbol level for individual libraries when running with a particular executable. To set the initial symbol
level to a value other than the default, make a selection in the Starting Level column. While debugging, you
can increase the symbol level using the Current Level column. This can be useful if you need more symbol
information while using GDB commands in the console. Clicking Reset sets all the starting symbol levels for
the libraries in the Module Information table to the default value.
A very powerful feature of Xcode is the ability to modify your executable while it is running and see the
results of your modification. This feature, which is implemented through the Fix command, is useful when
it takes a significant amount of time to reach the place in your application’s execution cycle that you want
to debug. You can use the feature to learn more about potential bug fixes or to see the immediate results
of code changes.
You use the Fix command in Xcode to modify an application at debug time and see the results of your
modification without restarting your debugging session. This feature can be particularly useful if it takes a
lot of time to reach your application’s current state of execution in the debugger. Rather than recompile your
project and restart your debugging session, you can make minor changes to your code, patch your executable,
and see the immediate results of your changes.
The Fix command is not intended as a replacement for building your product regularly. Instead, it is a
convenience feature for viewing the effect of small changes without restarting your debugging session.
Important: Use of the Fix command is subject to certain requirements and restrictions, which are listed in
"Fix Command Restrictions" (page 55).
Supported Fixes
Although there are many restrictions to what you can fix, there are also some features that are explicitly
supported by the Fix command, including the following:
■ Storing pointers to a patched function. GDB inserts code to jump from the old function to the newly
patched function. Thus, despite your code having a pointer to the original function, using that pointer
executes the patched version.
■ You can add local static variables to a file, but remember that GDB does not execute any initialization
code associated with them. Thus, if you declare a new class instance as a global static, GDB does not
execute any constructors or static initializers for the instance. there are also limitations on how those
variables behave after multiple patches.
■ You can add new C++ classes as part of a patch.
To learn about restrictions on the Fix command, see "Fix Command Restrictions" (page 55).
When it receives a patched binary, GDB compares that binary against the code in the application’s original
binary. GDB checks for several modifications that cannot be patched into a running application. If it detects
any of these modifications, it reports back to Xcode that it could not incorporate the patch. If this occurs,
you can stop debugging and rebuild your application, or continue debugging without the patch.
If GDB does not report any problems with your patch, it integrates the patched code into your application’s
memory image. It does this by making the following modifications:
If you patch a function that is on the stack, you may not see the results of that patch immediately. GDB is
capable of patching the function that is currently at the top of the stack. However, if you patch a function
that is further down the calling chain, the patch does not take effect until the next time you call it. Thus, the
function must return and be called again before it receives the patch. Until that time, the function on the
stack continues to execute the original code.
While your program is paused in the debugger, you can move the program counter around and resume
execution from any point in the current function. This feature lets you rerun a patched function from the
beginning, or from any point, to account for the changes you made.
If you quit your debugging session for any reason, you must rebuild your program to acquire any changes
made by patching. The effects of the Fix command are only applicable to your executable while it is active
in the debugger. The reason is that the command does not modify your program’s compiled object files.
Instead, it creates temporary object files and loads them into the memory space of your process dynamically.
When you quit the debugger, GDB discards the temporary object files containing the patches. Recompiling
your project recreates your application’s original object files from the patched code.
If you are running your executable in the debugger and you make changes to your source code, you can
patch your executable by choosing Run > Fix.
If you change more than one source file, you must fix each file separately. Xcode compiles the changes,
patches the executable to use the new code, and resumes execution from the location at which the program
was paused. If the changes to your code appear before the line at which execution is set to resume, you will
not see the effect of your change until that code is called again. To see the effect of your change, you can
manually alter the location at which execution resumes: When your program is paused, drag the PC
indicator—the red arrow pointing to the line of code where execution is paused—to the location at which
you want to resume execution.
Xcode automatically locates the correct target to use when creating the fix bundle. For example, if you are
debugging an application suite that relies on a framework you created, you can make a change in the
framework code. When you execute the Fix command, Xcode automatically uses the correct framework
target instead of the target associated with the running executable, to create the fix. Xcode also follows
references to targets in other projects.
2. Use your program until it reaches a state at which you want to modify its code without restarting the
debugging session.
You can use breakpoints with ignore-counts to facilitate this task. See "Viewing Breakpoints" (page 30)
for details.
3. In Xcode, modify the implementation file containing the code you want to modify, and save your changes.
The Fix command in Xcode is a powerful way to make small changes to a source file without restarting your
debugging session. Although powerful, there are some things you need to do before you can take advantage
of the Fix command. The command itself is enabled only when you are debugging an executable. In addition,
you must make sure you build your program as follows:
In general, if you build using the Debug build configurations provided by Xcode, the correct settings are
used. However, if you try to patch your executable and get a file-not-found error, check the build settings of
your target and make sure that debugging symbols are turned on, as described in “Building for Debugging”
in Xcode Project Management Guide. You can also check the build log to make sure that the patch bundle
was created.
The Fix command works on only one file at a time. If you make changes to multiple source files, you must
patch each file separately before continuing with your debugging session.
Important: If you attempt to patch multiple files, pause your application until you finish integrating all of
the patches.
GDB recognizes the following changes to your code and reports an error if you try to include them as part
of a fix:
■ Changes to the number or type of arguments in a function or method that is currently on the stack
■ Changes to the return type or name of a function or method that is currently on the stack
■ Changes to the number or type of local variables in a function or method that is currently on the stack
■ Changes to the type of global or local static variables
■ Symbol type redefinitions, that is, changing a function to a variable or a variable to a function
Important: Be aware that other conditions may also cause patched code to fail or exhibit other undefined
behavior. If you encounter such a problem, you should rebuild your program and start a new debugging
session.
With remote graphical debugging in Xcode, you can debug a program running on another computer as you
would any local executable, without resorting to the command line. Use remote debugging when you cannot
easily debug your program on the computer that it is running on. For example, you may be trying to debug
a full-screen application, such as a game, or a problem with event handling in your application’s GUI. Interacting
with the debugger on the same computer interferes with the execution of the program you are trying to
debug. In these cases, you have to debug the program remotely.
Note: Standard input (stdin) does not work with remote debugging; if you have a command-line tool that
requires user input, you must use the GDB command-line interface to debug your program remotely.
This chapter introduces remote debugging in Xcode and walks you through enabling remote debugging in
Xcode. To set up your project for remote debugging, you must perform the steps described in the following
sections:
■ "Configuring Remote Log-in" (page 59) describes how to configure your local computer and the remote
host to allow remote login using SSH public key authentication.
■ "Creating a Shared Build Location" (page 61) describes how to set up a shared build directory that both
computers can access via the same path.
■ "Configuring an Executable for Remote Debugging" (page 61) describes how to configure the executable
of the program you wish to debug for remote debugging in Xcode.
Remote debugging in Xcode relies on SSH public key authentication to create a secure connection with the
remote computer. To facilitate authentication, Xcode integrates with ssh-agent. This lets you use encrypted
private keys for added security without having to reenter your passphrase each time Xcode establishes a
connection to the remote host. If you already use a third-party utility to set up the environment variables
used by ssh-agent, Xcode attempts to use those settings. Otherwise, Xcode uses its own agent for
authentication.
Important: To debug remotely, Xcode must be installed on the debug host computer and the development
computer. For information about installing Xcode, see Xcode Installation Guide.
Before starting a remote debugging session, you need to be able to log in to the remote computer. To do
this, you must:
1. Turn on remote login on the computer that will host the program being debugged.
2. Ensure that you can connect to the remote host using SSH public key authentication.
If you are unsure whether you are using SSH public key authentication, you can test this by logging in
to the remote computer with ssh.
■ If you are prompted for the user’s password, you are not using public key authentication.
■ If you are prompted for a passphrase—or for nothing at all—you are already using public key
authentication.
If you are not set up to log in to the remote host using SSH public key authentication, you need to create a
public/private key pair, and configure the local and host computers to use it. You can do so with the following
steps:
ssh-keygen -t dsa
Note: Do not leave the passphrase empty; if you do so, your private key will be unencrypted.
2. Copy the public key to the authorized_keys file on the remote computer.
This file is usually stored at ~/.ssh/authorized_keys. If the authorized_keys file already exists on
the remote computer, be careful not to overwrite the file. You can add the public key, which is stored
in the file you specified to ssh-keygen (id_dsa.pub by default), by entering the following on the
command line:
3. Make sure that the authorized_keys file is not readable by anybody else.
Change the permissions on the file by entering the following on the command line:
From the command-line, type ssh <username>@<hostname>. Ensure that you are not asked for the
user’s password. If you did not leave it empty in step 1, you should be prompted for your passphrase,
as in the following example:
If you are debugging a GUI application, you must be logged in to the remote computer as the same user
that you connect to using ssh. This user must have permission to read the build products.
For remote debugging to work, both computers—both the local computer running Xcode and the remote
host running the program you are debugging—must have access to your project’s build products and
intermediate files. You can do this in either of two ways:
■ Create a single shared location. This is easiest with a network home directory, although you can use
any shared folder that both computers can access. In Xcode, set the build products and intermediates
location to this shared folder. If necessary, create symbolic links to the build folder on the remote host
so the path to the build products is the same on both computers. For details on how to set the location
of the build folder in your Xcode project, see “Build Locations” in Xcode Project Management Guide.
■ Copy the files to the remote host. Alternatively, you can copy the build products and intermediate files
over to the remote host after each build, although this is considerably less convenient. These files must
be located at the same path on the remote computer.
After you have configured both computers to allow for remote login and have set up a common build
products location, the last step is configuring the executable you want to debug remotely. You may consider
creating a separate custom executable environment for remote debugging. Using separate executable
environments, you can specify different options for debugging remotely and debugging locally and easily
switch between the two modes.
See “Executable-Environment Debugging Information” in Xcode Project Management Guide to learn how to
configure an executable for remote debugging.
To start a remote debugging session, make sure the active executable is correctly set, then build and debug
your product as normal. Before it launches the executable, Xcode displays an authentication dialog that asks
you to type in your passphrase. After you have authenticated once, Xcode does not prompt you for your
passphrase again until the next time you initiate a remote debugging session after restarting Xcode.
If you are experiencing problems debugging on the remote host, look in the console for error messages. To
view the console, choose Run > Console.
Many of the subsystems in Mac OS X include debugging facilities that can help you in your debugging tasks.
You can use most of these debugging facilities along with Xcode. Many debugging facilities are enabled or
disabled by setting an environment variable; you can modify the executable environment to set these
environment variables from Xcode. Xcode also includes several options for enabling specific debugging
options, such as libgmalloc (Guard Malloc), loading debug library variants, and stopping on Core Services
debugging functions (described in "Pausing on Core Services Debugging Functions" (page 38)). For more
on the many debugging facilities available in Mac OS X, see TN2124: Mac OS X Debugging Magic.
Many Mac OS X system frameworks include debug versions in addition to the production version. These
library variants are identified by their _debug suffix. Debug variants of the system frameworks usually include
debugging symbols, extra assertions, and often extra debugging facilities. You can modify the executable
environment to have Xcode use the debug variants for libraries that your program loads.
To use the debug variant of a library, open the Info window for the executable environment that you use to
run your program. In the General pane, choose “debug” from the menu “Use [suffix] suffix when loading
frameworks.”
Xcode also integrates Guard Malloc ( libgmalloc ) into the debugger interface. Guard Malloc helps you
debug memory problems by causing your program to crash on memory access errors. Because Guard Malloc
causes your program to crash, you should use Guard Malloc with the debugger. When a memory access error
occurs and your program crashes, you can look at the stack trace, determine exactly where the error occurred,
and jump to the location of the problem.
To enable debugging with Guard Malloc from Xcode, choose Debug > Enable Guard Malloc before starting
the debugging session. You can also use Guard Malloc with GDB from the command line, by setting the
DYLD_INSERT_LIBRARIES environment variable, as described in the man page for libgmalloc. To learn
how to set environment variables for development, see “Configuring Executable Environments” in Xcode
Project Management Guide.
Guard Malloc has a number of additional options available. You can take advantage of these by setting the
appropriate environment variables on the executable. In the inspector window for the executable, open the
Arguments pane and add the environment variables to the environment variables table at the bottom of
the window. See the man page for libgmalloc for additional details and information.
Xcode uses the DWARF debug information format to store your product’s debug data. In general, binaries
created for debugging have debug information embedded in them. The debug information for release
binaries, on the other hand, is normally stored in a separate file, the dSYM file. This practice reduces the size
of the binaries delivered to users of your product, which results in faster downloads and less space used in
media, such as DVDs.
In the unlikely event you need provide users with your product’s debug information (for example, to allow
users of a framework to troubleshoot a problem in its operation and give you file and line number information
about their call stacks), you send them the dSYM file that was generated alongside the release binary. You
can also rely on dSYM files to symbolize crash logs sent by your customers.
The “DEBUG_INFORMATION_FORMAT (Debug Information Format)” in Xcode Build Setting Reference build
setting lets you specify whether Xcode generates DWARF debug information and where to place it: In the
binary or in a dSYM file along the binary, as shown in Figure 12-1.
Xcode uses the dsymutil tool to generate dSYM files. See the tool’s man page for more information about
generating dSYM files.
65
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
CHAPTER 12
Debug Information Format
66
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
REVISION HISTORY
Date Notes
Added index.
Updated "Browsing Memory" (page 48) with information about using multiple
memory browsers.
Updated "Viewing Variables in the Debugger" (page 13) with information about
Unicode string display.
2008-05-16 New document that describes the Xcode debugging facilities and the
recommended debugging techniques.
67
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
REVISION HISTORY
Document Revision History
68
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
Index
expressions 47
B Fix and Continue 53
in the Console 25
breakpoint actions 35 low-level facilities for 63
breakpoints 29 memory, browsing. 48
actions 35 overview 9
file-line 31 pause on Core Services debugging functions 38
symbolic 31 processes 9
synthesized accessors 32 remote programs 59
breakpoints window shared libraries, viewing 50
illustrated 30 symbols 10
variables and memory, viewing 39
variables
display format 39
C DWARF debug information format 65
Console
debugging in the 25
F
Fix and Continue
D debugging with 53
overview 53
data formatters. See debugging.
debugger datatips 19
illustrated 19
debugger strip 18 M
illustrated 18
debugger window 11 memory browser 48
disassembly code, viewing 16 illustrated 49
illustrated 11 mini debugger 23
processor registers, viewing 16
stack frames in the 13
troubleshooting the 12
variables in the 13 P
debugging
patching code. See Fix and Continue, debugging with
in the debugger strip. See debugger strip
processes
in the debugger window. See debugger window
debugging 9
in the mini debugger. See mini debuger
in the text editor. See text editor, debugging in the
data formatters, using 39, 42
DWARF debug information format 65
execution control 29
69
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.
INDEX
S
shared libraries, debugging with 50
symbolic breakpoints 31
T
text editor, debugging in the 17
debugger datatips 19
gutter 18
illustrated 17
troubleshooting
debugger window 12
W
watchpoints 37
X
Xcode preferences
Debugging 27
70
2009-10-19 | © 2009 Apple Inc. All Rights Reserved.