18 Debugging WHAT'S IN THIS CHAPTER? Running your application Starting your application under the control of the debugger Setting breakpoints and creating smart breakpoints Examining, changing, and customizing the display of variables Debugging a program running on a remote system Getting your project to build is sometimes only half the battle. OK, let ’ s be honest; it ’ s often much less than half the battle. It ’ s a cruel fact of programming that your application will have bugs, design fl aws, and unexpected behavior. Object - oriented languages, modeling, good design, rigorous coding standards, and unit testing can reduce the number of bugs that creep into your code, but unless your application is trivial, it doesn ’ t matter how careful you ’ ve been, how many code reviews you ’ ve done, or how many “ best practices ” you ’ ve employed. Someday your application is simply not going to work the way you want it to, and you ’ ll have to fi nd out why. The tool of choice to answer that question is the debugger. The debugger is a magic window into your application. You can literally watch the internals of your program at work. You can stop your application, examine the values of variables, the state of other threads, and much more. Xcode even allows you to alter values and fi x some code while your application is still running — the equivalent of performing a heart transplant on an athlete who ’ s in the middle of running a marathon. ➤ ➤ ➤ ➤ ➤ c18.indd 437c18.indd 437 1/22/10 12:53:48 PM1/22/10 12:53:48 PM Download at getcoolebook.com 438 ❘ CHAPTER 18 DEBUGGING RUNNING YOUR APPLICATION Before getting into debugging, this section covers the trivial case of simply running your application. You can launch your program, more or less as it would be launched from the Finder or shell, using these commands: Build ➪ Build and Run (Command+Return) Build ➪ Build and Run - Breakpoints Off (Command+R) Run ➪ Run (Option+Command+Return) Run ➪ Run - Breakpoints Off (Option+Command+R) All of these commands launch the active executable produced by the most recent build. You choose the active executable much as you do the active target and build confi guration, described in the “ Choosing the Active Executable ” section. If your “ Run ” command has turned into a “ Debug ” command, it ’ s because you have breakpoints enabled. With breakpoints enabled, Run ➪ Run becomes Run ➪ Debug, Build ➪ Build and Run becomes Build ➪ Build and Debug, the Run toolbar button becomes a Debug button, and so on. Breakpoints are globally enabled and disabled by the Run ➪ Activate/Deactivate Breakpoints command. The run commands that also say “ Breakpoints Off ” fi rst deactivate all breakpoints before running the executable, equivalent to fi rst choosing Run ➪ Deactivate Breakpoints. The two Build and Run commands build the active target before starting your program. This is the most common way of running an application — notice that they have the simpler key combinations. It fi rst ensures that the target is fully built before starting your program. Remember to save your source fi les fi rst, or set the Always Save setting in the Building tab of Xcode ’ s preferences. The run commands are also accessible via your toolbar in the form of the Run/Debug button and the Build and Run/Debug buttons, shown in Figure 18 - 1. The Option key changes the action of the buttons from running with (breakpoints enabled) and without (breakpoints disabled) the debugger. ➤ ➤ ➤ ➤ FIGURE 18-1 c18.indd 438c18.indd 438 1/22/10 12:53:53 PM1/22/10 12:53:53 PM Download at getcoolebook.com Monitoring Your Process Running a program opens the Debugger Console window, shown in Figure 18 - 2. You can reopen this window at any time using the Run ➪ Console (Shift+Command+R) command. When your executable is launched via Xcode, this window is connected to the stdout, stdin, and stderr pipes of the process. In Xcode, the run window is sometimes referred to as a Pseudo Terminal and acts as a surrogate shell for the process, capturing any output or error messages and supplying any keyboard input to the program ’ s stdin pipe. For command - line tools, this is the main window for your application. For GUI applications, this window captures what would normally be sent to the System Console. For example, messages written using NSLog( ) are captured by the debugging console window when the application is started from within Xcode. FIGURE 18-2 You can modify these I/O connections, along with many other aspects of your program ’ s execution environment. See the “ Custom Executables ” section later in this chapter for more details. Stopping the Executable Whenever the executable is running, the Run/Debug button changes into a Stop button. You can unceremoniously terminate the running program (equivalent to a kill - KILL command or a Force Quit) using the Stop button or by choosing the Run ➪ Stop (Shift+Command+Return) command. Choosing the Active Executable The active executable determines what program is launched when you choose any of the run or debug commands. You can change the active executable using the Project ➪ Set Active Executable menu or using an Active Executable control that ’ s been added to any toolbar. In each menu, there is an item for every executable your project produces. Normally, changing the active target also changes the active executable. If your project produces two applications, Client and Server, changing from the Client target to the Server target also switches the active executable from Client to Server. Running Your Application ❘ 439 c18.indd 439c18.indd 439 1/22/10 12:54:06 PM1/22/10 12:54:06 PM Download at getcoolebook.com 440 ❘ CHAPTER 18 DEBUGGING In a number of circumstances this might not happen automatically. This is especially true when switching to or from an active target that does not produce an executable. Switching from an application target to an aggregate target (which produces nothing) or a framework target (that doesn ’ t produce anything that can be executed on its own) does not change the active executable. In these circumstances, you ’ ll need to choose the active executable yourself. You may sometimes want to launch a different executable from the one produced by the target. Say you are working on the Server application, but need to test it using the Client application. Select the Server as the active target and then switch the active executable to the Client. When you Build and Run, the Server gets built, but it ’ s the Client that gets launched. For the vast majority of projects, the executable produced by your application target is the executable that you want to run or debug. If you have a special situation, you may need to modify the environment in which your executable runs or create a custom executable. Both are explained toward the end of this chapter in the “ Custom Executables ” section. For now, you ’ ll concentrate on debugging simple executables produced by application and command - line targets. Everything here applies to custom executables as well. DEBUG ANYTIME, ANYWHERE The past few versions of Xcode have revealed a noticeable trend toward transparent and ubiquitous debugging. In earlier versions, debugging was performed almost exclusively in the single debugger window, with occasional side trips to the breakpoints and memory windows. Now, Xcode tries to bring the debugger to you whenever you need it, and wherever you happen to be, rather than making you go to the debugger. Xcode doesn ’ t even open the debugger window by default anymore. You can debug your applications in the same editor window that you write your code. You can set and modify breakpoints, view variables, and control execution. You can still utilize the traditional debugger window — which is still exceptionally useful for some debugging tasks. Furthermore, it provides some additional, and rather interesting, debugging interfaces. All of these interfaces are described in detail in later sections of this chapter, but I ’ ll summarize them here. Xcode 3.2 provides three primary debugging interfaces: In - Editor debugging The Debugger window The mini - debugger In - Editor debugging controls appear in all of your editing panes whenever a debug session is in progress, as shown in Figure 18 - 3. ➤ ➤ ➤ c18.indd 440c18.indd 440 1/22/10 12:54:07 PM1/22/10 12:54:07 PM Download at getcoolebook.com From your source fi le editing pane, you can: Set, enable, disable, and delete breakpoints Control program execution (pause, run, step over, step into, set out of, and so on) Examine variables Switch to a different task or stack frame The second big interface is the debugger window, shown in Figure 18 - 4. ➤ ➤ ➤ ➤ FIGURE 18-3 FIGURE 18-4 Debug Anytime, Anywhere ❘ 441 c18.indd 441c18.indd 441 1/22/10 12:54:08 PM1/22/10 12:54:08 PM Download at getcoolebook.com 442 ❘ CHAPTER 18 DEBUGGING 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. ➤ ➤ ➤ ➤ ➤ ➤ ➤ c18.indd 442c18.indd 442 1/22/10 12:54:08 PM1/22/10 12:54:08 PM Download at getcoolebook.com . without (breakpoints disabled) the debugger. ➤ ➤ ➤ ➤ FIGURE 18-1 c18.indd 438 c18.indd 438 1/22/10 12: 53: 53 PM1/22/10 12: 53: 53 PM Download at getcoolebook.com Monitoring Your Process Running a program. Stop button or by choosing the Run ➪ Stop (Shift+Command+Return) command. Choosing the Active Executable The active executable determines what program is launched when you choose any of the run. the middle of running a marathon. ➤ ➤ ➤ ➤ ➤ c18.indd 437 c18.indd 437 1/22/10 12: 53: 48 PM1/22/10 12: 53: 48 PM Download at getcoolebook.com 438 ❘ CHAPTER 18 DEBUGGING RUNNING YOUR APPLICATION Before