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

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

11 109 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 2,78 MB

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

Nội dung

If you are using the mini - debugger, the best choice is to open it automatically; by the very nature of programs that you ’ d want to use the mini - debugger with, opening it after you

Trang 1

500 ❘ CHAPTER 18 DEBUGGING

The Auto - Attach Debugger on Crash option causes the debugger to attach to the executable ’ s

process should it crash This is equivalent to stopping your executable immediately after it crashes,

but before the process is terminated, and issuing the Run ➪ Attach To Process command

The Auto - Attach Debugger on Crash option is really only meaningful in Mac

OS X 10.5 (Leopard) and earlier In 10.6 (Snow Leopard), Xcode preemptively starts the gdb debugger every time you launch your application from within Xcode, so in effect it ’ s already attached

The Additional Directories to Find Source File In pane lists the paths to where the debugger

can fi nd the source fi le used to build the executable being debugged Normally you don ’ t need

to add anything here because Xcode automatically searches all of the source directories in your

project However, if you have included source fi les outside your project or the executable was

built from source fi les that Xcode doesn ’ t know about — fi les in an externally built target, for

instance — add those directories here You can click the + button and type in the path, or drag a

folder from the Finder and drop it into the list

Selecting an Executable

The active executable that you select using the Project ➪ Set Active Executable menu is the

executable that will be launched when you choose any of the Run or Debug commands This is

typically the product produced by the active target, but it doesn ’ t have to be After selecting a target,

you can change the active executable to an executable produced by another target or to a custom

executable that you ’ ve created

When you switch targets, Xcode examines the active executable If the active executable is the

one created for the product produced by the current target, and the target you are switching to

produces an executable product, the active executable is changed to match the new active target

For most projects, this means that the active executable will “ follow ” the active target as you change

between them However, if you have targets that don ’ t produce an executable, or have created and

made custom executables active, changing the target may not change the executable You need to

be especially watchful if you have created aggregate targets An aggregate target that builds both a

client and server application will not select an active executable when you make that target active

You must specify which executable, the client or the server, needs to be launched when you choose

Run or Debug

DEBUGGER PREFERENCES

You can use the Debugging pane of the Xcode preferences, shown in Figure 18 - 42, to confi gure a

few common debugging features

Trang 2

Starting on the left are the Fonts and Colors preferences Select a category of text from the pop

-up menu, and then change the font, style, and color of the font using the Set Font button With these settings, you can alter the appearance of text that appears in the run and Debugger Console windows This makes it possible, or at least easier, to differentiate between the text output by the debugger and the text output by your program By default, Xcode colors the debugger ’ s prompt and bolds the text sent to the debugger All output appears the same

The Instruction Pointer Highlight color is the color used to highlight the currently executing line of source code in the debugger If you prefer to see a different color, click the color well or drag a color into the color well to change it

The On Start setting lets you choose to automatically open certain windows when you start your application using the debugger The choices are:

Do Nothing Show Console Show Debugger Show Console & Debugger Show Mini Debugger

If you tend to use the in - editor debugging controls, set this to Show Console Otherwise, choose Show Debugger or Show Console & Debugger so that the debugger window will automatically open when you begin debugging

If you are using the mini - debugger, the best choice is to open it automatically; by the very nature

of programs that you ’ d want to use the mini - debugger with, opening it after you ’ ve started your application can be awkward

The GDB Log setting will optionally write an extremely detailed log of your debugging session to a text fi le for later analysis This is particularly useful if you ’ re trying to diagnose a problem with gdb

FIGURE 18-42

Trang 3

502 ❘CHAPTER 18 DEBUGGING

commands, breakpoint actions, and so on Enter the path to where you want the fi le written — just

remember that this is a global setting that affects all projects If the path is left empty, Xcode writes

to a temporary fi le

Load Symbols Lazily controls the default level of symbols that load when modules and dynamic

libraries are loaded into memory Enabling lazy loading causes only the minimal amount of

debug information to be loaded for each module initially, deferring the loading of more complete

symbol information until it ’ s needed Turning it off causes the debugger to immediately load

everything it knows about every library loaded into memory This makes starting the debugger

slower, but makes more complete debug information available See the “ Shared Libraries ” section

for more details

The Disassembly Style setting controls the output of the Build ➪ Show Assembly Code command

Clearing the In - Editor Debugger Controls will turn off the normal in - editor debugging features in

each editor pane You ’ ll have to use the debugger window for your debugging

REMOTE DEBUGGING

The gdb debugger supports remote debugging The debugger runs on one computer, while your

application runs on a different computer What actually happens is that another copy of the

debugger is started on the remote computer along with your program, and the two debuggers

communicate via a network connection The remote instance of the debugger transmits all of the

pertinent information about your application to the local debugger so you can see what ’ s going

on Commands issued to the local debugger are, similarly, forwarded to the remote debugger for

execution

Remote debugging permits you to test your application in an environment different from that of

your development system A typical requirement is the need to debug your application using an

earlier version of the operating system Xcode, and even the computer you ’ re developing on, may

not be compatible with the OS you need to run under Even if it were, building your application

and then rebooting your computer into an older version of the OS to test it is both tedious and

unproductive

Remote debugging is also useful for debugging interactive code Video games and drag - and - drop

handlers can be nearly impossible to debug on a single machine, because the sequence of user events

needed to test the problem are interrupted by the debugger itself The mini - debugger is a great tool,

but it still requires user interaction on the same system running the application

Debugging your application remotely requires some special confi guration of both computers

Specifi cally, you must:

Pre - authorize an ssh login account on the remote computer

Create a shared build location accessible by both computers via the same path

Confi gure the executable for remote debugging

Remote debugging works through the Secure Shell ( ssh ) remote login facility built into Mac

OS X ssh provides secure communications paths using a public - key encryption system The

primary reason for using ssh for remote debugger communications is not security — although

Trang 4

that ’ s valuable if you need it Instead, Xcode leverages a powerful feature of ssh called tunneling

that lets it communicate with a remote debugger process as if it were running locally But the side effect of using ssh is that it requires a secure connection to be established fi rst, and that requires authentication Normally this is done interactively using a password For debugging, this is awkward To get around the need for a password, you need pre - authorized access to the remote machine so that the local computer can connect directly to the remote computer without any human intervention

You create pre - authorized ssh logins by manually generating and exchanging parts of a public/

private key pair (If you are curious, a typical ssh login authenticates a user and then spontaneously generates a temporary public/private key pair for that session Pre - creating a public/private key pair skips both of these steps.) To create a pre - authorized login on the remote computer, follow these steps (the commands you would enter are in bold):

1. On the local computer, open a Terminal window and generate an RSA public/private key pair using the ssh - keygen tool:

local:~ james$ ssh-keygen -b 2048 -t rsa

Generating public/private rsa key pair.

Enter file in which to save the key (/Users/james/.ssh/id_rsa):

Enter passphrase (empty for no passphrase):

Enter same passphrase again:

2. Press Return when Xcode asks for a fi lename This uses the default RSA fi lename for your

account If Xcode asks to overwrite the fi le, answer with a y Enter a passphrase or press

Return to leave it blank (A blank passphrase is less secure, but is still acceptable and more convenient in a low - security environment.) Confi rm the passphrase by entering it again If you are successful, a new private key is written to ~/.ssh/id_rsa and your public key is written to ~/.ssh/id_rsa.pub , as follows:

Your identifi cation has been saved in /Users/james/.ssh/id_rsa.

Your public key has been saved in /Users/james/.ssh/id_rsa.pub.

3. On the remote computer, make sure Remote Login is enabled in the Sharing pane of the System Preferences This allows ssh connections from other computers

4. Log in to the remote computer using the account you plan to debug under This verifi es that the network connection works and that the remote computer is confi gured to accept ssh logins In this example, I ’ m logging in to the computer whiterabbit using a special account I created just for testing Use the account name and address of your remote computer in place

of test and whiterabbit.local

local:~ james$ ssh test@whiterabbit.local

Password:

Last login: Wed Sep 21 15:39:42 2005 Welcome to Darwin!

whiterabbit:~ test$

5. You now need to transfer the public key you just generated to the remote computer

One way is to use ssh ’ s fi le transfer capability to send the id_rsa.pub fi le to the remote computer Open a second Terminal window (you still have more work to do in

Trang 5

504 ❘CHAPTER 18 DEBUGGING

the remote shell you just connected to, so leave that alone for the moment) and enter the following command:

local:~ james$ scp ~/.ssh/id_rsa.pub test@whiterabbit.local:development_rsa.pub

Password:

id_rsa.pub 100% 1123 1.1KB/s 00:00

Again, supply the password of the remote account and substitute the correct account name and computer address This command copies the id_rsa.pub fi le from the local .ssh

directory into the development_rsa.pub fi le in the home folder of the remote computer

6. Return to the Terminal window with the ssh shell session on the remote computer Use the

ls command to verify that the development_rsa.pub fi le was transferred

7. You now need to append the public encryption key in the development_rsa.pub fi le to the

list of authorized computers for this account To do this, use the following commands:

whiterabbit:~ test$ mkdir ~/.ssh

whiterabbit:~ test$ cat ~/development_rsa.pub > > ~/.ssh/authorized_keys

whiterabbit:~ test$ rm ~/development_rsa.pub

whiterabbit:~ test$ chmod go-rwx ~/.ssh/authorized_keys

The .ssh directory and authorized_keys fi le may already exist, in which case you don ’ t want to overwrite them You just want to append the new key to the existing fi le This is a text fi le, so it can also be edited using nano , vim , or your favorite text editor The last two commands delete the public key fi le that was transferred and rescind all non - user access to the authorized_keys fi le for security purposes

8. The remote computer is now pre - authorized to accept secure connections from your current

account on the local computer to the account you just confi gured on the remote computer

Verify this by logging out of the current remote session and connecting again, like this:

whiterabbit:~ test$ exit

logout Connection to whiterabbit.local closed

local:~ james$ ssh test@whiterabbit.local

Enter passphrase for key ‘/Users/james/.ssh/id_rsa’:

Last login: Tue Oct 25 09:49:46 2005 from marchhare.local Welcome to Darwin!

whiterabbit:~ test$

This time, ssh prompted for the passphrase used to generate the key, not for the password

of the test account on the local computer If successful, you know that ssh used the key for this computer to connect to the test account on the remote computer If you want to change any of these variables in the future — you want to connect from a different development machine or from a different account or to a different account — you must repeat these steps

The next step is to create a shared build location accessible to both computers Both the

development and remote computer must have direct access to the entire build folder containing both

the fi nal product as well as all intermediate build fi les More importantly, the UNIX path to the

folder must be identical on both computers You have three easy ways of accomplishing this

The fi rst, and probably simplest, solution is to employ a third - party fi le server Create a build folder on a fi le server separate from your local or remote computer (The “ Build Locations ” section in Chapter 17 discussed different ways of relocating your project ’ s build

Trang 6

folder.) You can now mount the build folder on both the local and remote computer using the same path

The second is a hybrid approach Confi gure your project to build to a local folder in a com-mon, publicly accessible folder like /Users/Shared/Projects/DistantBugs Turn on the

fi le sharing services of OS X and connect to it from the local machine Now create a sym-bolic link on the remote computer so that the build folder can be reached on both machines using the same path You must use the command - line tools to create symbolic links The following example mounts the main volume of a development system (Griffi n, in this exam-ple) as a network volume on a remote computer, and a symbol link is created in the remote computer ’ s Shared folder that links to the same folder on the development system:

ln -s /Volumes/Griffin/Users/Shared/Projects /Users/Shared/Projects

Now, any build folders that are created in the development computer ’ s /Users/Shared/

Projects folder will appear at the same location in the remote computer ’ s fi le system

The third method of getting both computers access to the same build folder would be to simply copy the entire build folder to the remote computer For a one - shot test, this might

be the easiest solution However, if you were constantly rebuilding the project, this would be both inconvenient and ineffi cient You could automate the process by creating a target script phrase to copy the contents of the build folder to the remote computer If you decide to go this route, consider using a utility like rsync to quickly transfer only the portions of the build folder that change after each build Remember that the location of the copy must reside at the same location as the original, or at least have an equivalent UNIX path

The last step in this process is to confi gure Xcode to start the debugging session remotely You do this is in the Debugging pane of the executable ’ s Info window, previously shown in Figure 18 - 41

Check the Debug Executable Remotely Via SSH option When you do this, the Standard Input/

Output option changes to Pipe Leave it that way; this choice must be set to Pipe for remote

debugging to work

Start your debugging session as you normally would The fi rst time you do, Xcode asks for your passphrase to decode the private key you generated earlier, as shown in Figure 18 - 43 Once it has your private key, it connects to the remote computer and starts the debugging session After this point, debugging your application remotely isn ’ t signifi cantly different from debugging it locally

FIGURE 18-43

Trang 7

506 ❘ CHAPTER 18 DEBUGGING

If anything goes wrong — problems connecting to the remote computer, accessing the product on

the remote computer, or starting the debugger — consult the debugger console window for clues

Both the ssh client and the debugger output copious diagnostic messages to the console Anything

that goes wrong should be documented there

DEBUGGING AIDES

A number of miscellaneous tools and features are scattered around the debugger, Xcode, and the

operating system itself that will help you fi nd bugs in your code The “ Custom Executables ” section

covered loading the debug variant of frameworks and enabling Debugger() and DebugStr() calls

The following sections describe a few more Xcode facilities

Catching a Throw

The command Run ➪ Stop on Objective - C Exceptions command enables an implied breakpoint

whenever an Objective - C exception is thrown You can enable or disable this breakpoint at any time

during your debugging

Stopping for Debugger() and DebugStr()

The Run ➪ Stop on Debugger()/DebugStr() command sets an implied breakpoint whenever your

application calls the Debugger() or DebugStr() commands Normally these function calls are

ignored The command in the Debug menu enables this feature for all of the executables in your

project If you want to have Debugger() and DebugStr() break only in certain executables, disable

the menu item and enable the same setting for selected executables in their Debugger pane

Guard Malloc

A very useful debugging feature for C programmers is the Guard Malloc library Choosing the

Run ➪ Enable Guard Malloc command before you start the debugging session causes your

executable to be linked against the Guard Malloc ( libgmalloc ) library instead of the normal

malloc routines provided by the system The Guard Malloc library uses the virtual memory features

of the CPU to map every block of memory allocated using malloc( into its own address space

If your program attempts to access any data outside the immediate boundaries of the allocated

block, an EXC_BAD_ACCESS error occurs, crashing your program at the exact point where the illegal

access occurred

It should be noted that Guard Malloc can signifi cantly slow down your application, but the

additional execution time is usually worth it, because out - of - bounds memory accesses are

particularly diffi cult to debug

Debug Variables

Debug variables are either environment variables or preference property values that invoke special

behavior in the libraries and frameworks and are useful for debugging

Trang 8

There is also a wide range of debugging support functions that your application can call directly, but a discussion of those is beyond the scope of this book The best resource is Apple ’ s Technical Note #2124, Mac OS X Debugging Magic You can fi nd it in the Xcode documentation

Environment variables can be set using the Arguments pane of the executable ’ s Info window

Preference values can be set using the defaults command - line tool You can read the man page on the defaults tool for the details of setting user default values, but here ’ s a simple example:

defaults write com.my.SimpleApp NSShowAllViews YES

The com.my.SimpleApp fi le is the user preferences fi le associated with the application By default, this is the Identifi er set in the target ’ s Properties pane The command sets the NSShowAllViews

property to YES , which causes the AppKit framework to draw a colored border around every NSView Setting property values only works for Carbon and Cocoa applications that use the user defaults framework

The following table describes a few environment variables useful for C programming:

MallocScribble Fills deallocated memory with 0x55s If your program reads the data again,

it should be obvious in the debugger that the data is from a stale block

MallocGuardEdges Adds guard pages before and after large allocation blocks This will

catch attempts to access data well beyond the edge of each allocated block It can be used independently of the Guard Malloc library

MallocStackLogging Logs the stack state for each allocated block There are tools that will

read this log and assist you in debugging memory allocation problems, especially memory leaks

If you think you have a problem with loading dynamic libraries, try some of the environment variables described in the following table:

DYLD_IMAGE_SUFFIX Searches for libraries with this suffi x fi rst Use this to load alternate

variants of libraries A lot of the system libraries include debug versions that can be loaded by setting the suffi x to _debug

DYLD_PRINT_LIBRARIES Logs the names of each library, as it is loaded If you think you ’ re

loading the wrong dynamic library, set this variable to 1

DYLD_PRINT_LIBRARIES _POST_LAUNCH

Logs the names of loaded libraries, but it only starts logging after your application has started executing This avoids logging a lot of the core libraries

DYLD_PREBIND_DEBUG Logs pre - binding diagnostics information about your application

Trang 9

508 ❘CHAPTER 18 DEBUGGING

If you ’ re debugging memory leak or retain/release problems in Cocoa, consider setting some of the

environment variables described in the following table:

NSZombieEnabled NO If this is set to YES , NSObjects are “ zombifi ed ”

instead of being deallocated A zombie object has all of its message handlers replaced with a call that will break into the debugger This will catch an attempt to send a message to an object that has already been released and deallocated

NSDeallocateZombies NO Set this to YES and the memory for zombie

objects will actually be released The NO setting

is the safest, but can result in memory leaks that themselves may cause your application to misbehave

NSHangOnUncaughtException NO Normally an uncaught NSException will cause a

Cocoa application to terminate Set this variable

to YES and it will simply hang instead, allowing you to break into it using the debugger and examine its state

NSEnableAutoreleasePool YES Setting this value to NO defeats the functionality

of auto - release pools Use this if you want to keep around all of the objects that an auto -release pool would normally -release

NSAutoreleaseFreedObject

CheckEnabled

NO This is a very handy setting for fi nding double

-release bugs Setting this variable to YES will cause the auto - release pool to log an error message if the pool contains an object that has already been released

NSAutoreleaseHighWaterMark This is a useful diagnostics tool to check for

situations where you are putting an excessive number of objects into an auto - release pool Set

it to a number other than 0 and the system will log a warning whenever more than that number of objects have been added to the pool

NSAutoreleaseHighWater

Resolution

0 Use this setting to log a warning message for

every N number of objects above the high - water mark level The high - water mark level emits a single warning when the number exceeds that value This setting emits a warning for every increment Setting the high - water mark to 1000 and the resolution to 50 would log a message when there were 1000, 1050, 1100, 1050, objects in any auto - release pool

Trang 10

The two preference settings described in the following table are useful when you ’ re debugging an AppKit application that is having drawing or layout problems You must set preferences in the preference fi le of the application before you launch it

NSShowAllViews Defi ne this preference and set it to YES and the AppKit window manager

will draw a colored border around each NSView in the application This makes it very easy to see spacing and layout problems

NSShowAllDrawing Defi ne this preference and set it to YES and AppKit will draw a colored

rectangle before drawing each NSView This makes it very easy to see what components in your windows are drawing, when, and in what order

Also check out the various Quartz Debug features

This is just the tip of the iceberg There are literally hundreds of variables, system calls, and development tools to help you track down and debug your application Most are collected and

maintained in Apple Technical Note #2124, Mac OS X Debugging Magic , which you can fi nd

in the Xcode documentation or read online at http://developer.apple.com/mac/library/

technotes/tn2004/tn2124.html

SUMMARY

You should now have at your disposal a cornucopia of tools and techniques for isolating, trapping, examining, and correcting any aberrant behavior in your application You are likely to spend a lot of time using the debugger Knowing how to harness the debugger ’ s capabilities can save you hours of time

Getting your application to build and execute correctly may be all you intended to accomplish For some applications, even this isn ’ t the end of the development process You may not be satisfi ed that

your application merely runs You want it to run fast — and that is the subject of the next chapter

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

TỪ KHÓA LIÊN QUAN