Combined with breakpoint controls in the gutter which, more than likely, were already visible and additional symbol inspectors called datatips , the in - editor debugging controls allow
Trang 1A machine trap instruction is essentially a programmatic crash It can be inserted using an assembly directive, as depicted in the following listing:
#if defined( ppc ) || defined( ppc64 ) asm { trap }
#endif
#if defined( i386 ) || defined( x86_64 ) asm { int 3 }
#endif These machine language trap instructions cause your application to immediately stop If launched from Xcode, Xcode will attach the debugger as it would for any unrecoverable exception If a trap
is executed outside of Xcode, your program will immediately terminate The system will treat your application as if it had crashed
Also see the “ Custom Executables ” section Whether Xcode stops for Debugger() calls or automatically attaches itself when the process crashes can be disabled for individual executables
IN - EDITOR DEBUGGING
Xcode ’ s in - editor debugging tools let you perform basic and common debugging actions right
in your editing window This means that in many situations you can edit, compile, run, and debug your application without ever switching to another Xcode window or view
When a debugging session starts, the debugger strip appears at the top of your editor pane, as shown in Figure 18 - 6 Combined with breakpoint controls in the gutter (which, more than likely,
were already visible) and additional symbol inspectors (called datatips ), the in - editor debugging
controls allow you to do three things:
Modify breakpoints Control execution Inspect variables
➤
➤
➤
FIGURE 18-6
A setting in the debugging pane of the Xcode preferences enables the in - editor debugging controls If you don ’ t see the in - editor debugging controls, check your preferences
In - Editor Debugging ❘ 449
Trang 2450 ❘CHAPTER 18 DEBUGGING
Editing Breakpoints
Breakpoints are described in detail in the “ Breakpoints ” section of this chapter, but here ’ s the short
lesson:
Click a line number in the gutter to create a breakpoint Click a breakpoint to enable/disable it
Drag a breakpoint to a new line to relocate it Drag a breakpoint out of the gutter to delete it Double - click a breakpoint to reveal it in the breakpoints window
Controlling Execution
The red arrow in the gutter, shown in Figure 18 - 3, indicates the line of code containing the CPU ’ s
program counter This is, essentially, where your program is executing — with some caveats that I ’ ll
get to in a moment
Selecting the Thread and Stack Frame
The debugger strip appears in the editor pane above the navigation ribbon On the left is a pop - up
control that selects the thread with which you want to work On the right is another pop - up control
that lists and selects the stack frame with which you want to work In between are a series of
debugger control buttons
The gutter ’ s program counter indicator is for the selected stack frame of the selected thread If you
switch threads using the left - hand control, the program pointer moves to indicate where that thread
is currently executing If you choose a different stack frame, it shows where execution will continue
when that stack frame is restored — in other words, the code that called the code in the subsequent
stack frame
Running and Stepping Through Code
In between the task and stack frame pop - up menus are the debugger actions These are listed, from
left to right, in the following table:
(De)activate Breakpoints Run ➪ (De)activate Breakpoints Control+Command+\
➤
➤
➤
➤
➤
Trang 3The fi rst fi ve actions are described in detail in the “ Controlling the Debugger ” section The last two simply open the debugger window (see “ The Debugger Window ” section) or the debugging console window (already mentioned in the “ Monitoring Your Process ” section)
Hover Step Controls
If you hover your cursor over a line number in the gutter that corresponds to executable code, or over a function or method name in the code, one of a number of step controls appears
Hovering the cursor over the currently executing code line reveals a tiny continue button, as shown
underneath the cursor in Figure 18 - 7 If you carefully slide the cursor over to the button and click it, Xcode lets the program continue executing
FIGURE 18-7
FIGURE 18-8
Hovering the cursor over any other executable line in the gutter reveals a continue to here button, as
shown in Figure 18 - 8 The continue to here action sets a temporary breakpoint and then continues execution Assuming the application doesn ’ t encounter another breakpoint fi rst, the process will run until it gets to the line over which you were hovering
The Continue to Here command can also be found in the contextual menu when you Right/Control - click a line the gutter This can be faster than trying to use the hover controls
Hovering over a function or method call, as shown in Figure 18 - 9, reveals a targeted step into
button Much like the continue to here action, it sets a temporary breakpoint at the beginning of the
In - Editor Debugging❘ 451
Trang 4452 ❘CHAPTER 18 DEBUGGING
function you ’ re hovering over and then lets the application continue execution The program runs
until it steps into the function you targeted
FIGURE 18-9
Viewing Variables
Variables in your running application can be examined simply by hovering the cursor over
the variable name This displays a datatip , as shown in Figure 18 - 10, that reveals the type, name,
and value of the variable
FIGURE 18-10
Simple variables display a single row describing its type, name, and current value
Complex variables, like objects and structures, include a disclosure triangle that expands to reveal
its individual instance variables or fi elds Complex instance variables can themselves be expanded,
letting you “ drill down ” in search of the variables for which you ’ re looking
Datatips only appear for variables in the scope of the current stack frame of the currently selected thread Changing the thread or stack frame from the debugger strip brings a new set of variables into scope The section “ The Threads Pane ” illustrates this in more detail
Trang 5By default, the expansion of subvariables is automatic, but you can turn that off Clicking the disclosure triangle of an expanded variable collapses it again
A datatip row may contain one of two active controls One is a value editor Most mutable scalar values can be changed simply by clicking its value in the datatip, also shown in Figure 18 - 10
The other control is a datatip menu, which appears as two arrows on the left - hand side of the datatip Clicking the arrows pops up the a datatip menu, as shown in Figure 18 - 11
FIGURE 18-11
From the datatip menu you can dump (print) the variable ’ s value to the debugger console, open the variable in its own window, jump to the symbol ’ s defi nition or documentation, enable/disable data formatters, control the order in which subvariables are displayed, and turn datatip auto - expansion
on or off
Variable windows, memory browser windows, types, and data formatters are all described later in the “ Examining Data ” section
THE DEBUGGER WINDOW
The debugger window, shown in Figure 18 - 12, is the master control center for debugging
Debugging controls in the editor or mini - debugger are designed to be unobtrusive or appear only when requested The debugger window is just the opposite; it presents as much information about the variables and state of your application as possible The debugging features accessible from the editor pane or the mini - debugger are all duplicates of the features in the debugger window, so the detailed descriptions of each are included in these sections
The Debugger Window ❘ 453
Trang 6454 ❘CHAPTER 18 DEBUGGING
Each project has its own debugger window You can open the debugger window at any time using
the Run ➪ Debugger (Command+Shift+Y) command You can minimize or close the debugger
window — if only to get it out of your way — without upsetting the debug session Reopen the
debugger window again and resume where you left off
The debugger window has three main panes: the threads pane, the variables pane, and the listing
or editor pane The debugger pane has an alternate vertical layout to the one shown in Figure 18 - 12
Use the Run ➪ Debugger Display ➪ Vertical/Horizontal Layout command to switch between the
two The vertical layout splits the window vertically, with the threads and variables panes on the left
and the entire vertical pane on the right dedicated to the listing or editor pane Choose the style that
you fi nd most comfortable
You can resize all three panes by dragging the small grey thumb bar that appears at the nexus of the
three panes
The Threads Pane
The threads pane displays the stack of the active thread, as shown in Figure 18 - 13 Each entry in the
list represents a single stack frame, and the selected entry defi nes the active stack frame A frame
contains the return address of the caller and all of the function ’ s automatic variables If the address
of the function can be translated into a name, the function ’ s name is displayed Otherwise the
address of the function is listed
FIGURE 18-12
Trang 7When you stop an application in the debugger, the debugger stops all threads, but the pane displays the call stack of the thread that hit the breakpoint The left column indicates the relative depth of each function in the call stack The name of the function currently executing is displayed at the top of the list and always has a stack depth of 0 The name of the function that called the currently executing function is listed underneath that and has a stack depth of 1, and so on all the way back
to the function that started the thread
For the debugger, there are only functions, structures, and variables Different languages refer to subroutines using various terminologies: procedure, function, member function, method, subroutine, or message handler Ultimately, each becomes a block of code at an address in memory When this book uses the words “ function ” or “ subroutine, ” substitute the term of your preferred paradigm
The contents of the variables pane and the initial contents of the editor pane are determined by the current selection in the threads pane When you stop an application, the current (top) function in the call stack of the stopped thread is selected Select another function in the call stack, and the variables and editor pane change to display the variables and execution location in that function
This allows you to examine not only the variables of the current function, but also the variables and calling address of the functions that called the current function
You can view another call stack by selecting a different thread from the pop - up menu at the top of the pane, as shown in Figure 18 - 14
FIGURE 18-13
The Debugger Window❘ 455
Trang 8456 ❘CHAPTER 18 DEBUGGING
You can also step through the threads in your application using these two commands:
Run ➪ Next Thread (Control+Option+Command+ ↑ ) Run ➪ Previous Thread (Control+Option+Command+ ↓ ) Change to another thread, and you can examine the local variables and calling address of any frame
on that thread ’ s stack Depending on the language and run time library used, threads may or may
not have readable descriptions If they do, the description will appear next to the thread ’ s identifi er
The Run ➪ Sync With Debugger command is a kind of navigation “ home ” for the debugger
window It reselects the thread and top - most stack frame that caused the debugger to stop, and
jumps to the program ’ s execution location in the editor pane
The Listing or Editor Pane
The listing or editor pane displays the source code of your application, a disassembly listing, or
both The latter combination is shown in Figure 18 - 15 The debugger chooses a view automatically
when it needs to display a breakpoint or calling location If the debugger can correlate the program
location with a source fi le, it displays the source code in an editor pane
➤
➤
FIGURE 18-14
FIGURE 18-15
Trang 9This is a full - featured editor pane, allowing you to edit your source code right in the debugger window It also contains all of the breakpoints, hover step controls, and datatips described earlier in the “ In - Editor Debugging ” section The only thing it doesn ’ t have is the debugging strip, because all
of those functions are provided elsewhere in the debugger window
You can choose an alternate source code view using one of the following commands:
Run ➪ Debugger Display ➪ Source Only Run ➪ Debugger Display ➪ Source and Disassembly Run ➪ Debugger Display ➪ Disassembly Only
If the debugger cannot determine a source fi le that corresponds to the program ’ s location, there is
no source view; it displays only the disassembly of the machine codes and the disassembly display commands have no effect Similarly, only languages that compile directly into assembly language have a disassembly view; Java and AppleScript programs do not show a disassembly view of their byte code or tokens
Breakpoints and the current execution location are indicated in the gutter of the editor pane Breakpoints appear as dark blue (enabled), light blue (disabled), or yellow (invalid) markers
The program counter (PC) indicator appears as a red arrow The breakpoint and location indicators are so critical to the effective use of the debugger that the gutter display is turned on whenever you are in a debug session If your Xcode Preferences are set not to display the gutter in the editor, the gutters disappear again at the end of your debug session
The program - counter indicator always points to the current execution location for the selected thread and stack frame In a source fi le, it points to the source line most closely associated with the program - counter position In the disassembly listing, it points to the exact instruction If the top (level 0) stack frame is selected, the arrow indicates where the current thread is executing
Select another stack frame in the list and it indicates the location where the stack frame above
it was called
Because the meaning of the PC indicator is relative, make sure you pay attention
to what stack frame you have selected If you choose another stack frame, the
PC indicator points to where the current execution location was called from, not where it is Using a command like Step Over does not step to the next instruction after the PC indicator It steps to the next instruction in the top stack frame, where the program is actually stopped
The Variables Pane
The variables pane displays the known data variables for the selected stack frame The key word
here is known The debugger must have debug symbol information that describes the structure for
the selected stack frame If there is no description available, it cannot interpret or display any data values on the stack and the pane is empty You will encounter this most often when you stop an application in a system framework or library routine
➤
➤
➤
The Debugger Window❘ 457
Trang 10458 ❘CHAPTER 18 DEBUGGING
Variable Groups
Variables in the display are organized into a hierarchy of groups The top - level groups are listed in
the following table:
VARIABLE GROUP DESCRIPTION
Arguments The parameters passed to the current function
Locals The automatic variables allocated in the stack frame
File Statics Local static variables allocated in the same module
Globals Potentially, any global variable in the application
Properties AppleScript properties
Registers The CPU ’ s hardware registers
If there are no variables of a given type, the group containing that type is not displayed: a simple C
function with no parameters does not display an Arguments group A method with no automatic
variables has no Local group
Although the Arguments group is technically just more local variables, Xcode groups them for
convenience In object - oriented languages, the arguments include the implied variables such as this
or self Expand the this or self object to view the instance variables of the current object
The Locals group contains the local (also known as automatic or stack) variables allocated on the
stack frame
The File Statics group contains any static variables defi ned in the code ’ s module The scope is
immaterial; the defi ned variables may be local or global
The Globals group contains any global variables you want to examine in the applications Because
this could, potentially, contain hundreds if not thousands of variables (remember that every library
and framework that your application is linked to can declare globals), this group must be manually
populated with just the symbols you want to examine This is explained later in the “ Viewing
Global Variables ” section
The Registers group, or groups, depends on the architecture of the assembly code and your current
processor Interpreted languages like Java and AppleScript won ’ t have a Registers group CPUs with
vector processing units, fl oating - point calculation units, or CPUs that have a separate set of 64 - bit
registers may display addition register groups
Exploring Variables
Variables are listed by name Structures, arrays, and objects appear as groups in the listing Expose
the contents of a group to examine its member variables, just like you did with the datatips The
Value column shows the interpreted value of the variable For simple types (integers, fl oats, strings)
it ’ s the textual representation of the value For arrays, structures, and objects it ’ s a summary of its
content The summary can be very generic or quite specifi c, as you ’ ll soon see