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

Lập trình Wrox Professional Xcode 3 cho Mac OS part 59 ppt

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

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

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Định dạng
Số trang 8
Dung lượng 2,53 MB

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

Nội dung

You can see where you can debug from almost anywhere in the Xcode interface, but you can also debug your application anytime; you can launch your application normally and then later deci

Trang 1

The debugger window includes an editing pane, so everything you can do in an editing pane can

also be done in the debugger window In addition, the debugger window provides:

A structured list of all in - scope variables The CPU registers

Access to global variables Advanced data inspectors

A stack frame list Thread selection The debugger window is where you turn if you want to explore other stack frames, switch to

another thread, want to see a list of all variables in scope simultaneously, see global variables, want

to examine variables in more detail, or want to modify variables

The third interface is the mini - debugger It ’ s a minimal debugging interface designed for use with

full - screen applications and other situations where getting to the debugger window is awkward or

inconvenient The mini - debugger is described in later sections

You can see where you can debug from almost anywhere in the Xcode interface, but you can also debug

your application anytime; you can launch your application normally and then later decide that you want

to debug it; Xcode will interrupt the process, attach its debugger, and hand over control to you

In fact, that ’ s really the primary reason for the Run ➪ Run - Breakpoints Off (Option+ Command+R)

command After starting your application, all you have to do is create, enable, or reactivate (Run ➪

Activate Breakpoints) a breakpoint; Xcode will invoke the debugger, have it attach itself to your

running executable (if needed), set the requested breakpoints, and let the debugger take over — just

as if you had started your application under the control of the debugger in the fi rst place In Mac

OS X 10.6 (Snow Leopard), Xcode keeps the GDB debugging running all the time, so it ’ s even more

responsive

Before any serious debugging can take place, you must fi rst prepare your project for debugging

BUILT TO BE DEBUGGED

The take - home message of this section is this:

Before debugging, profi ling, or analyzing your code, you must fi rst build it using the Debug build confi guration

It ’ s an essential requirement for doing any kind of debugging or analysis If you ’ re in a hurry,

switch your active build confi guration to Debug and skip to the next section If you ’ re interested in

knowing why, keep reading

How you build your application affects its ability to be debugged The quintessential quality of a

modern programming language is that it allows a developer to express procedures symbolically,

letting the compiler deal with the ugly details of how to accomplish those procedures in machine

code Listing 18 - 1 shows just how obtuse the machine code for a few “ simple ” lines of programming

source can be The source code is shown in the listing, followed by the resulting Intel machine code

Trang 2

The debugger has the unenviable job of reversing this process — it must examine the raw machine code and translate that back into something that corresponds to the functions, methods, code blocks, classes, structures, and variable names defi ned in your source code (You see this process at work later in Figure 18 - 6.)

LISTING 18 - 1: Compiled source code

SOURCE CODE

- (void)dealloc {

free(byteArray);

[super dealloc];

}

COMPILED ASSEMBLY CODE

pushl %ebp movl %esp, %ebp pushl %ebx subl $36, %esp movl 8(%ebp), %ebx movl 4(%ebx), %eax movl %eax, (%esp) call _free movl %ebx, -16(%ebp) movl L_OBJC_CLASS_SieveOfEratosthenes+4, %eax movl %eax, -12(%ebp)

leal -16(%ebp), %edx movl L_OBJC_SELECTOR_REFERENCES_2, %eax movl %eax, 4(%esp)

movl %edx, (%esp) call _objc_msgSendSuper addl $36, %esp

popl %ebx leave ret

To accomplish this feat, the debugger needs a lot of help That help comes in the form of debugger symbols produced by the compiler Debugger symbols are a kind of massive cross - index They contain information like “ the machine instruction at byte offset 12,738 corresponds to line 83 of the source fi le breakme.c ” If you set a breakpoint at line 83 of breakme.c , the debugger knows it needs to stop your program at the instruction found at offset 12,738 If your program crashes at (or near) the machine instruction at offset 12,738, the debugger can tell you that your program crashed

at (or near) line 83 of breakme.c The debugger symbols contain similar information about data structures, classes, automatic variables, and so on You must request that these debugger symbols be produced when your application is compiled If you have created your project using one of the Xcode templates, you should have a Release and a Debug build confi guration The Debug build confi guration, shown in Figure 18 - 5, for your program ’ s target has the following build settings:

Generate Debug Symbols: On

Trang 3

Optimization Level: None Fix & Continue: Off

FIGURE 18-5

Generate Debug Symbols enables the full array of debugger symbols in the compiler, detailing every

aspect of your code for the debugger Without it, the debugger is next to useless This information

is produced when each source fi le is compiled, it takes a little extra time to compile, and produces

a lot of data — quite often more data than your actual program — which the debugger has to load

All of this slows down both compilation and launch time If you are debugging a massive amount of

code, you may elect to generate debug symbols only for some modules and not others For example,

you may generate debugger symbols for your main application code but not some well - tested library

routines This speeds up building and debugging, but limits your debugging to the portion of your

code that has debugger symbols

The Debug Information Format defi nes which fi le format to use to write the debugging information

DWARF with dSYM File is the modern format and should be your fi rst choice DWARF and Stabs

are older formats that embed the debugging information in the executable

If you ’ re using the modern DWARF with dSYM File debug symbols format, the legacy build settings Strip Linked Product and Strip Debug Symbols During Copy are largely superfl uous Legacy debugging symbols were stored in the executable fi les themselves, and later stripped off during the deployment phase

of your Release build confi guration The modern dSYM fi le writes the debugging information to a separate symbol fi le, so the executable is essentially already

“ stripped ” of its debug information

If you ’ re developing a legacy application created with an earlier version of Xcode, update your debug format to DWARF with dSYM File and make sure the Strip Debug Symbols During Copy build setting is set to NO Leaving Strip Debug Symbols During Copy on will interfere with code signing, which is critical to iPhone and modern Mac OS X applications

Trang 4

While you ’ re debugging, the optimization of your code should be set to None The reason why goes back to how debuggers work Optimization, by its very nature, is logic in the compiler that reorganizes, reorders, rewrites, and often eliminates code that it fi nds to be ineffi cient or redundant

Take the following code fragment as an example:

Line 100: int i=0;

Line 101: for (i=1; i < argc; i++)

With optimization turned on, the compiler eliminates the statement i=0 because the result of that assignment is never used In the debugger, it now becomes impossible to set a breakpoint at line

100 because the code that corresponds to that line of source code doesn ’ t exist in your compiled application More advanced optimization techniques, such as loop unrolling or instruction reordering, can produce even more bizarre aberrations, such as programs whose statements execute out of order (for example, line 101, then 103, then 102) It might be impossible to stop an application at a certain point in your source code, or step through your code one line at a time

Skeptical readers are invited to enable full optimization and then attempt to debug their application Fix & Continue is a feature, covered later in “ The Magic Fix, ” that allows you to make limited code changes in your application while your application is running That is, you don ’ t have to stop your program, change your code, rebuild, and restart You simply change your code and keep executing

To use this feature, your compiled object code must contain additional information that the Fix &

Continue feature needs If you leave this build setting off, you can still debug your code, but the Fix & Continue feature is disabled

The Release build confi guration for new projects has the opposite build settings: no debug symbols, symbols stripped, normal optimization, and no Fix & Continue If you have created your own targets or build confi gurations, you ’ ll need to set them up accordingly

Note that Xcode project templates defi ne many of these settings in the target ’ s build settings

If you have a multiple target project, you can easily misconfi gure the settings in one target and not realize it Or, you can set them in the project build settings, where they will be promptly ignored For these reasons, I recommend moving these basic debug settings into the project build settings level for multi - target projects, and then override these settings only in those targets that require something different (which is rare) This way, you can adjust the level of debugger symbols produced (for example) with a single build setting, rather than having to change this setting in every target

TIP TO REMEMBER

If you think you ’ re having problems getting your build settings right, create a temporary build confi guration to experiment with After you have everything working, you can compare that to the original, or just delete the one that doesn ’ t work If you ’ ve made a lot of changes and really want to know what the differences are, export all of your build settings by copying and pasting them into two separate text fi les You can then compare them visually or using a diff tool

Trang 5

DEBUGGING EXECUTABLES

With the preliminaries out of the way, you ’ re ready to debug your application Getting started is as

easy as running your program Choose any of these commands to start your application under the

control of the debugger:

Build ➪ Build and Debug (Command+Return) Build ➪ Build and Debug - Breakpoints On (Command+Y) Run ➪ Debug (Option+Command+Return)

Run ➪ Debug - Breakpoints On (Option+Command+Y)

As mentioned in the “ Running Your Application ” section, the two unqualifi ed “ Debug ” commands

change to “ Run ” commands when breakpoints are inactive The two “ Breakpoints On ” commands

simply activate breakpoints and start debugging, identical to Run ➪ Activate Breakpoints, followed

by Build/Run ➪ Debug

All of these commands start your program under the control of the debugger The time from which

the debugger starts your program until it fi nishes is referred to as the debug session

An alternative is available in the targets group if you would like to build and then run or debug a

target that is not the active target or executable Right/Control - click the target ’ s icon in the target

smart group and choose either the Build and Start or the Build and Debug command The effects

are the same as changing the active target to the one selected, issuing a Build and Run/Debug

command, and then switching the active target back to what it was originally

You can have only one debug session active for a project However, you can have concurrent debug

sessions from separate projects A Client and a Server application, both built using separate projects,

could each be running in separate debug sessions simultaneously

The Process Behind the Curtain

Like most modern integrated development environments (IDEs), the Xcode application doesn ’ t

perform the actual debugging — or compilation, or linking, or profi ling — of your application

Xcode simply provides an intelligent interface to the command - line tools that do the bulk of the

work In the case of debugging, the work is usually done by gdb , the GNU Debugger

I say usually, because Xcode can also use other debuggers It understands the JavaBug and

AppleScript debuggers, but if you ’ re doing Mac OS X or iPhone OS development, you ’ ll be

using gdb

Xcode doesn ’ t try to hide the debugger; there are plenty of places where you can interact with

the debugger directly What it tries to do is eliminate much of the tedium of using command - line

debuggers by replacing the command line with an interactive, graphical user interface

So while you ’ re working your way through this chapter, keep this in mind:

Almost every debugging task you undertake in Xcode is eventually translated into a com-mand sent to gdb , or whatever debugger you ’ re using

Trang 6

Debugger Spoken Here

Another great advantage to using an intermediate debugger is that your debugger interface remains largely the same regardless of the target application environment Xcode can debug an application

in any of the following environments:

A local process running in Mac OS X

A remote process running on another Mac OS X system

An iPhone application running in a local simulator process

An iPhone application running on a remote device Debugging an application running on the same computer system is the most common scenario, but

by no means the only one The section “ Remote Debugging, ” later in this chapter, shows you how

to debug a process interactively that is running on a different computer system

iPhone application development would seem like it is worlds apart from desktop application development While the design and implementation might be substantially different, the development tools remain almost identical

You might have expected a substantial portion of this chapter to be dedicated to the iPhone simulator and iPhone native debugging, but there ’ s really very little to say Though there ’ s some prerequisite confi guration required before an iPhone or iPod Touch can debug applications (see Chapter 22), there is virtually no difference between debugging an iPhone application running

on an iPod Touch and debugging a Cocoa application running on your development system Almost everything in this chapter applies to both

ATTACHING TO RUNNING EXECUTABLES

As mentioned earlier, the Xcode debugger can attach itself to an already running process on your

local system, extracting debug information and taking control of its execution Xcode may do this for one of four reasons:

You create a new breakpoint or enable an existing breakpoint You reactivate existing breakpoints

An application you started in Xcode crashes or encounters a trap You choose a process from the Run ➪ Attach to Process menu The fi rst three all apply to the currently running executable started via Xcode, but the behavior is

a little different depending on which operating system you ’ re running If you ’ re running Mac OS

X 10.5 (Leopard) or earlier, your application is launched normally and the gdb debugger is started and attached when requested If your running Mac OS X 10.6 (Snow Leopard) or later, Xcode preemptively starts gdb when it launches your application, but lets your application “ run free ” When you enable breakpoints, gdb steps in, enables breakpoints, and assumes control of your application ’ s execution The primary advantage is speed; gdb is launched quietly in the background, and springs instantly into action when requested

Trang 7

Whether gdb is preemptively started ahead of time or launched post hoc is largely immaterial, except in a few circumstances Some of the system frameworks include anti - piracy code that either resists being debugged or disables certain features in the presence of the debugger If you ’ re working with QuickTime or similar libraries, you may have to manually launch your application and then use the Run ➪ Attach to Process command at some strategic time

Once your application is running, creating or enabling any breakpoint signals to Xcode that you

want to take control of the application with the debugger The workfl ow you ’ d typically use this in

looks something like this:

1. Write some code

2. Build and run the application

3. Discover that something ’ s not working right

4. Start the debugger and have it attach to the already running application

5. Debug the problem

The Run ➪ Attach to Process menu lets you attach the Xcode debugger to a process that Xcode

didn ’ t launch In this menu are all of the running applications If you need to attach to a background

process, choose the Run ➪ Attach to Process ➪ Process ID command and enter the process ID you

want to debug These commands are useful when you want to debug a process that you started

outside of Xcode (say, from the Finder) or for processes started programmatically; for instance,

you ’ ve written a Cocoa application that executes a command - line tool

When attaching to a running process, Xcode does its best to match the executable with a target in

the current project If it can ’ t it will still attach to the process, but the amount of useful debugging

information will be extremely limited

The third reason Xcode will attach to your running application involves a trap, uncaught signal,

or other exception that would normally cause the process to exit immediately Xcode automatically

intercepts these exceptions and — rather than letting your application terminate — attaches the

debugger You are left in a debug session with the program suspended at the location that caused

the fatal problem You can examine the threads, stack, variables, and other information in an

attempt to determine what went wrong

You might fi nd it useful to intentionally cause a trap programmatically To do this, you can add a

debugger trap or a hard trap instruction to your code The Debugger() or DebugStr() functions

request the debugger For the most part, they act like programmatically defi ned breakpoints

They will cause the debugger to stop the application, or attach the debugger to an already running

application If left in your code and run in the absence of a debugger, these functions will

write a message to the system console every time they are executed — but they won ’ t terminate your

application

Trang 8

A 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

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

TỪ KHÓA LIÊN QUAN