1. Trang chủ
  2. » Công Nghệ Thông Tin

Lập trình Wrox Professional Xcode 3 cho Mac OS part 65 doc

11 98 0
Tài liệu đã được kiểm tra trùng lặp

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 11
Dung lượng 3,04 MB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

The debug version of your application must be built with the following: The Fix & Continue GCC_ENABLE_FIX_AND_CONTINUE build setting checked Compiled using gcc version 3.3 or later Ful

Trang 1

Object Descriptions

Like data formatters, many object - oriented languages have adopted conventions for converting any

object into a textual representation In Java, this is the toString() function Objective - C uses the

- [NSObject description] method If you are using an object that supports one of these standards,

you can use the Run ➪ Variables View ➪ Print Description to Console command The debugger

invokes the standard “ to string ” function on the object and sends the result to the debugger console

WATCHPOINTS

Watchpoints are breakpoints for data You can make any variable a watchpoint Whenever the

debugger detects that the value of that variable has changed, it stops your application

Watchpoints sound great, but they are fairly limited The biggest problem is that your application

can ’ t execute any code where the watchpoint variable is out of context, so they are mostly useful for

global variables that are always in scope and for catching state changes in a loop

You set a watchpoint by fi rst selecting a variable in the variables pane Choose the Run ➪ Variables

View ➪ Watch Variable command This places a magnifying glass icon next to the variable as shown

in Figure 18 - 35 Start the program executing again, and it breaks at the point just before the variable

is altered with a dialog box explaining what is about to happen, also shown in Figure 18 - 35

FIGURE 18-35

You can choose to acknowledge the event and leave the watchpoint set, or disable the watchpoint

by clicking the Disable button Watchpoints are automatically deleted whenever your application

exits the context where the watchpoint variable exists Watchpoints are not retained between debug

sessions

You can create an effect similar to a watchpoint using a breakpoint conditional like i!=0 It ’ s not as convenient as a watchpoint, but it ’ s more durable

To remove a watchpoint, select the variable being watched and choose Run ➪ Variables View ➪

Watch Variable again to remove the check mark

Trang 2

CHANGING DATA AND CODE

So far, this chapter has taken a rather passive approach to debugging You ’ ve viewed code and variables in countless ways, but you haven ’ t actually changed anything Xcode lets you alter both data and code while your application is executing This can be a huge time - saver when you ’ re debugging You can change the values of parameters to test specifi c cases, or correct a value that was miscalculated and continue testing

Changing variables is easy Select a primitive variable and choose the Edit Value command from either the Run ➪ Variables View menu or the Right/Control - click contextual menu in the variables pane You can also double - click the value of the variable right in the variables pane Edit the value and press Return The only acceptable forms are decimal, octal (beginning with a zero), or hexadecimal (beginning with 0x ) To enter a character you need to translate that character into a decimal or hexadecimal value The Code Table view of the system ’ s Character Palette is particularly useful in looking up character code values

If the variable is a pointer, you can change the address of the pointer or you can expand the variable and Xcode allows you to change any primitive values to which the pointer points

The Magic Fix

It ’ s simple enough to poke a new value into a variable and continue executing, but what if the code itself is incorrect? Xcode allows you to fi x that too

This bit of magic — and it really is something close to magic — is a feature called Fix & Continue

As the name implies, it enables you to recompile code in your application and continue debugging

it without restarting your program Use of this feature depends on some prerequisites The debug

version of your application must be built with the following:

The Fix & Continue ( GCC_ENABLE_FIX_AND_CONTINUE ) build setting checked Compiled using gcc version 3.3 or later

Full debug symbols

No optimization

If, for any reason, the debugger can ’ t use Fix & Continue, the Fix command will be disabled while debugging

Using this feature is deceptively simple Say, for example, you discover a bug in your source code while you ’ re debugging Listing 18 - 5 shows a common programming mistake: a loop with a missing increment statement

LISTING 18 - 5: Bad loop

Token findOneToken( const char* s ) {

while ( *s!='\0' & & isspace(*s) ) s++;

continues

Trang 3

LISTING 18-5 (continued)

Token token;

token.word = s;

token.length = 0;

while ( *s!='\0' )

{

char c = *s;

if (isspace(c))

break;

token.length++;

}

return (token);

}

After stepping through the second loop a few times, it becomes obvious that it gets stuck because

the statement c = *s should have been c = *s++

To correct this code, simply edit the statement so that it reads c = *s++ and choose Run ➪ Fix or

click the Fix button in the debugger ’ s toolbar The source for this fi le is recompiled, the new code

is loaded into your application ’ s code space replacing the old version of findOneToken , and the

program counter changes to point to the equivalent line in the new code

If that was all that needed to be done, you could continue debugging the application Replacing the

buggy code has, unfortunately, created another situation Before you added the increment operator,

the s variable wasn ’ t being incremented — but token.length was The length value now has a

non - zero value and won ’ t agree with the length of the string when the function returns

Can you continue debugging your application without having to restart it? You have two ways of

addressing this The fi rst would be to use the variables pane and simply edit the value of token

.length , setting it back to 0 Another way is to alter the program counter so that the program

continues executing at a different location in the code Here the PC indicator is being dragged

back up to the token.length = 0 statement so that the entire second loop starts over from the

beginning, as shown in Figure 18 - 36

FIGURE 18-36

Trang 4

When the execution is continued, the program starts again at the top of the (now bug - free) loop, reinitializes token.length to 0 , and executes correctly

Magic Fix Limitations

Fix & Continue does have some limitations Here are a few:

Fix is not supported by all debuggers Support for Fix & Continue comes and goes in gdb

You cannot redefi ne typedef variables, data structures, classes, or function arguments

You cannot redefi ne the automatic variables on the stack frame

You cannot redefi ne global data variables

You cannot make any change to your application ’ s resources, such as icon or nib fi les

You cannot fi x a bad reference to a function by renaming the function

In short, you can make any change that alters only the executable code of one or more functions.

You can ’ t make a fi x that alters the data types or linkages that are, or could be, used anywhere else

in the application

You should be aware of a couple other caveats about how Fix & Continue works Fix & Continue replaces the code of a function that was executing and changes the current program counter so that execution continues in the new code However, it does not change the program counter in any other stack frame Say that Function A calls Function B If you stop the program in Function B

and fi x Function A, when Function B returns it will return to the old Function A, not the

corrected one The corrected Function A won ’ t be called until something else calls Function A again

Fix & Continue only compiles and replaces the in - memory image of a single fi le If you make changes in several fi les, you will need to perform a Fix & Continue on each one

Also note that Fix & Continue only patches the memory image of the running application

It does not alter the original executable fi le that was produced by the last build If you restart your application the old (bug - ridden) version is executed Worse, the executable code is now out of sync with the modifi ed source fi les Make sure you follow each debugging session where you use Fix & Continue with a new build to incorporate the changes you made into the fi nal product

DEBUGGER CONSOLE

The debugger console has been mentioned several times in this chapter To access it, choose the Run ➪ Console (Shift+Command+R) command, or click the Console button in the debugger window ’ s toolbar This opens the debugger console window, shown in Figure 18 - 37

Trang 5

FIGURE 18-37

Like many of Xcode ’ s interfaces, the debugger window is just a graphical front - end to the gdb (or

Java, or AppleScript) debugger that runs underneath it The debugger console window is a shell

window that interacts with the debugger process directly When you click the Continue button in

Xcode ’ s debugger window, Xcode just sends a continue command to gdb Any information that

gdb outputs is visible in the debugger console window

If you are having problems with the debugger, the debugger console window is the fi rst place

to look Problems setting breakpoints, resolving symbols, or evaluating expressions are

logged there

More interesting is that the debugger console window is a fully interactive terminal window

Through this window you can type commands directly into the debugger The debugger provides

many features that are not available through the graphical interface provided by Xcode Of course,

this requires an understanding of the gdb (or Java debugger) commands and their syntax You can

learn the basics by entering the help command at the (gdb) or JavaBug > prompt The AppleScript

debugger has no interactive commands

SHARED LIBRARIES

One miscellaneous debugger tool is the shared library window, shown in Figure 18 - 38 Opened with

the Run ➪ Show ➪ Shared Libraries command, it shows the status of the shared libraries that your

application is linked to Most of the information here concerns how many of the debugging symbols

for each library have been loaded into the debugger

Trang 6

The Module column shows the name of each shared library The Address column shows the address

in the application ’ s memory space where the library has been loaded If the fi eld is blank, the library has not been loaded into memory yet The complete path to the selected library is shown at the bottom of the window

The Starting Level and Current Level columns show what level of debugging symbols should be loaded for each library when the debugger starts and right now, respectively The debugger can avoid loading symbols for a library, load only the external declarations, or read all debugging symbols including source fi le line information The less debugging information loaded, the faster the debugger starts up and runs — and the less it knows about your application

Normally, the debugger loads only the external declarations This is the superfi cial information about the library Whenever it needs to know more detailed information, it automatically loads any remaining debugger symbols that describe data structures, source fi le line numbers, and so on

You can watch this process at work Start an application and set a breakpoint very early in the application, like at the fi rst line of main() Open the shared library window and the global variables window Start looking through the libraries in the global variables window As you browse each library for global variables, the status of the loaded symbols in the shared library window changes from None or External to All as you force the debugger to load additional debugging symbols for each library — debug symbol information that the debugger needs to display the global variables

in each library

You can manually load the symbols for a library into memory by changing the setting in the Current Level column The change occurs immediately The Starting Level column determines what the Current Level column will be set to when the library is initially loaded You can set this to

a particular level or use the Default setting If set to Default, the level used will either be the Default Level for System Libraries or User Libraries, as appropriate, set with the two global pop - up menus

at the top of the window The default level of External is known as “ lazy ” symbol loading; the idea

is to get your application running in the debugger as quickly as possible by loading only the minimal amount of information and worrying about the details later You can disable Lazy Symbol Loading

FIGURE 18-38

Trang 7

in the Debugger pane of the Xcode Preferences Disabling Lazy Symbol Loading changes the User

Libraries default from External to All

The Reset button at the bottom sets the Starting Level of all libraries to Default

You can manually add or remove libraries from the list by clicking the + and – buttons at the bottom

of the window To add a library, browse to the location of the library and open it Remember that

in the fi le browser, the Shift+Command+G key combination opens the Go To sheet, allowing you to

enter a path to normally invisible directories like /usr/lib

The shared libraries window is mostly informational, but it can be used to give hints to the

debugger telling it to load — or avoid loading — debug symbol information at strategic times If you

are debugging a very large application, this can speed up the debugger by not loading unnecessary

symbols or speed up your debugging workfl ow by preloading symbols you need You cannot use

this window to force libraries to load or unload or to force symbol information that the debugger is

using out of memory

CUSTOM EXECUTABLES

So far you ’ ve been running and debugging simple applications without much thought to

the environment in which those applications were running When you created a target

to produce your application, Xcode also created a matching product and an executable The

executable, which appears in the Executables smart group of the Groups & Files pane, defi nes

the execution environment for your application It defi nes what binary program will be executed

when it is launched, what parameters and environment variables will be passed to it, and what its

I/O fi le descriptors will be attached to You can customize the environment settings of an executable

created by Xcode, or you can create your own

You may want to customize or create a custom executable for several reasons For example:

You need to pass command - line parameters to the process when it is started

You need to set environment variables for the process, or choose a different working directory before the process is started

You want to redirect the input or output of the tool to something other than the run or debugging console windows

You need to debug an executable that Xcode didn ’ t produce or for which Xcode doesn ’ t automatically create a product and executable, such as a program produced by an external build process

Your executable is launched via a script or some other process

The project you are developing is a plug - in or a framework that can ’ t be executed on its own You need to launch an application that will load the plug - in and exercise it

General Settings

Open the Info window for an existing executable, or choose the Project ➪ New Custom Executable

command to create a new one The General tab of the executable ’ s Info window, shown in

Figure 18 - 39, controls the environment for that executable when it is run

Trang 8

The Path option is the path, relative to the build product ’ s directory, to the program that will be launched when the executable is started Normally this is the binary application produced by your target Change this if you want a different program executed instead An example would be a UNIX program that is started by a shell script that checks the state of the program, gathers confi guration information, and so on, before launching the binary program If your product is started by such a script, enter the path to the script here

At the bottom of the window is the current or working directory that will be set before the executable is launched This is important to some executables that expect to fi nd resources or perform work on fi les relative to the current directory Normally this is set to the build directory for the product That is, the current directory will be the same directory that contains the executable

The build product directory will change depending on which build confi guration is active You can alternatively choose the project directory or a custom directory Enter the custom directory path, or click the Choose button to browse for a folder

The Use Suffi x When Loading Frameworks option passes a special fl ag to the dynamic linker It tells the system ’ s run time library loader to search for alternate versions of framework libraries Many libraries are provided in alternate versions designed to aid in debugging or profi ling They may include additional integrity checks or log informational messages to the system log that are useful during development When set to No, the loader links your application to the standard system libraries

The Use For Standard Input/Output option determines where the stdout, stdin, and stderr fi le descriptors will be connected when the executable is launched The Pseudo Terminal connects your application to the run or debugging console you ’ ve been using throughout this chapter The Pipe choice is only useful for remote debugging, as described later The System Console choice directs the program ’ s output to the system console Macintosh applications launched by the user, and command - line programs launched without a shell, normally have their output redirected to the

FIGURE 18-39

Trang 9

system console log You can review the system console log using the Console utility provided with

Mac OS X When set to the System Console choice, stdin is connected to null

Arguments and Environment

Use the Arguments pane to pass additional arguments and environment variables to your program

This can be extremely useful for testing command - line applications or setting special features of the

run time system

To add an argument, click the + button beneath the Arguments pane and type in the argument value,

as shown in Figure 18 - 40 You can later edit arguments by double - clicking their values and reorder

them by dragging The check box in the left column is an enabled setting Only arguments that are

enabled are passed to the executable This makes it easy to keep several commonly used arguments in

the list and quickly select just the ones you want Select an argument and click the – button to delete

it entirely

The environment variables pane works exactly the same way as the arguments, except that this

pane defi nes named variables that are defi ned in the environment of the process The values of

environment variables can also reference any of the following build settings: SYMROOT , SRCROOT ,

OBJROOT , BUILT_PRODUCTS_DIR , and TARGET_TEMP_DIR Chapter 17 covers referencing build

settings in general and the meaning of these build settings in particular

FIGURE 18-40

Debugging

The Debugging pane, shown in Figure 18 - 41, controls additional settings that affect the execution

environment of your program when you launch it under the control of the debugger The When Using

option controls which debugger Xcode will start to debug your application The debugger chosen

must be capable of debugging the kind of application that the executable produces The Java debugger

cannot debug a binary executable Xcode sets this appropriately for executable products produced

from targets For custom executables, you need to tell Xcode which debugger is appropriate

Trang 10

The Use For Standard Input/Output option controls the connections to the program ’ s I/O

You may want to set this to System Console if the output of the program is obscuring the output

of the debugger itself in the Debugger Console window It is also possible to distinguish between the output of the debugger and your program by coloring their text differently in the Debugger Console window (See the Debugger pane settings in the Xcode preferences.) If you are doing remote debugging, this option must be set to Pipe

The next two options confi gure the gdb debugger for remote execution The “ Remote Debugging ” section in this chapter explains how to confi gure a program for remote debugging

The Start Executable After Starting Debugger option automatically starts your application running

as soon as the debugger is loaded Normally this is checked, but you may not want this to happen

Turning this option off launches the debugger, but performs no further action This permits you the opportunity of making special adjustments in the debugging environment, such as setting breakpoints or editing static variables, before the program starts running You can even use the debugger command to attach to an already running instance of your application, rather than launching a new one

The Break on Debugger() And DebugStr() option sets the USERBREAK environment variable before your application is started The presence of this environment variable causes the Debugger() and DebugStr() functions defi ned in Core Services to send a SIGINT signal to your program if either of these functions are called Without this setting, these functions do nothing or just log a message to the console When running under the debugger, a SIGINT signal suspends your program just as if it hit a breakpoint This option sets this environment variable only when the executable is launched for debugging To have it set all of the time, set the USERBREAK environment variable to 1 in the Arguments pane

FIGURE 18-41

Ngày đăng: 04/07/2014, 06:20