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 108 0

Đ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

Nội dung

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. c18.indd 500c18.indd 500 1/22/10 12:56:08 PM1/22/10 12:56:08 PM Download at getcoolebook.com 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 Debugger Preferences ❘ 501 c18.indd 501c18.indd 501 1/22/10 12:56:14 PM1/22/10 12:56:14 PM Download at getcoolebook.com 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 ➤ ➤ ➤ c18.indd 502c18.indd 502 1/22/10 12:56:15 PM1/22/10 12:56:15 PM Download at getcoolebook.com 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 Remote Debugging ❘ 503 c18.indd 503c18.indd 503 1/22/10 12:56:15 PM1/22/10 12:56:15 PM Download at getcoolebook.com 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 ➤ c18.indd 504c18.indd 504 1/22/10 12:56:16 PM1/22/10 12:56:16 PM Download at getcoolebook.com 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 Remote Debugging ❘ 505 c18.indd 505c18.indd 505 1/22/10 12:56:17 PM1/22/10 12:56:17 PM Download at getcoolebook.com 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. c18.indd 506c18.indd 506 1/22/10 12:56:18 PM1/22/10 12:56:18 PM Download at getcoolebook.com 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: ENVIRONMENT VARIABLE DESCRIPTION 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: ENVIRONMENT VARIABLE DESCRIPTION DYLD_IMAGE_SUFFIX Searches for libraries with this su 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 su 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. Debugging Aides ❘ 507 c18.indd 507c18.indd 507 1/22/10 12:56:18 PM1/22/10 12:56:18 PM Download at getcoolebook.com 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: ENVIRONMENT VARIABLE DEFAULT DESCRIPTION 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 0 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. c18.indd 508c18.indd 508 1/22/10 12:56:24 PM1/22/10 12:56:24 PM Download at getcoolebook.com 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. PREFERENCE KEY DESCRIPTION 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. Summary ❘ 509 c18.indd 509c18.indd 509 1/22/10 12:56:25 PM1/22/10 12:56:25 PM Download at getcoolebook.com . 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. 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. 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

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