This Mac software development tool helps you easily debug programs written for both 680x0 and PowerPC processors
Tom Thompson
The Mac programmer's life got complicated when Apple introduced the PowerPC-based Power Macs. There are new choices in development tools that generate PowerPC object code. Also, the Power Mac's run-time architecture has been revamped to support DLLs and objects called code fragments (see ``The Power Mac's Run-Time Architecture,'' April BYTE). This means there are two new volumes of Inside Macintosh to read, along with the usual complement of technical notes, to obtain information on this new system software.
However, since the Power Macs provide better native performance than other platforms, they promise great opportunities for those who make the effort t
o write native (i.e., PowerPC) programs. Furthermore, those code fragments, which are the building blocks of Power Mac programs, let you readily access system globals or other application data without resorting to assembly language. This simplifies a Mac program's design tremendously.
You've still got to debug those native programs, though, especially as you learn the nuances of code fragments and other PowerPC-specific details. This means using a native debugger. Surprisingly, there are very few of those for the Power Mac. There's Apple's Macsbug 6.5, a debugger written in 680x0 code that relies on the Power Mac's 68LC040 emulator to operate. This version of Macsbug still only interprets 680x0 processor instructions and registers. There are special resources called dcmds (shorthand for debugger commands) that can enhance Macsbug's capabilities, much as a Photoshop plug-in adds new features to Photoshop. Apple provided early Power Mac developers with dcmds that enabled Macsbug to interpret PowerPC inst
ructions and display the processor registers. However, at this writing, Apple has not decided whether to offer these dcmds to the developer community at large.
This leaves serious PowerPC program debugging to a product from Jasik Designs called The Debugger V2. Either the program's author, Steve Jasik, has a lot of brass, or The Debugger is loaded with enough unique features to justify the name.
Based on my experience using The Debugger on several Power Mac programming jobs, it earns its title easily. It's an industrial-strength debugger that runs on both 680x0-based Macs and Power Macs. On Power Macs, whose operating system is a mix of 680x0 and PowerPC code, The Debugger handles both processor instruction sets simultaneously. It provides low-level glimpses of either processor's instructions and registers, yet it can supply a high-level view of a faulty program as source code. It also lets you easily display the contents of the program's variables and data structures. These and other features t
hat I'll describe below make The Debugger well worth its $350 price tag.
Types of Debuggers
Before going into specific details on The Debugger, it's important to review what types of debuggers there are. Macsbug is a low-level or assembly language debugger. Low-level debuggers typically operate as close to the metal as they can, using a minimum number of operating-system resources. Thus, such debuggers are very robust. They typically continue to run even when a program bug wreaks havoc on most of the operating system.
Because they rely so little on the operating-system code, low-level debuggers can be used to debug parts of the operating system or specialized code such as menu definition functions (used to create floating tool palettes), drivers, and Extensions. The big disadvantage of low-level debuggers is that because they shun the use of system services, they must sport a rudimentary interface. This interface requires that you remember what commands to type in to adjust the program counte
r, set a breakpoint, or dump a section of memory.
A high-level or source debugger levers off the services of the Mac OS to provide easy access to the program being debugged. It typically displays the program as source code rather than as processor instructions. Variables and data structures can be examined by name, and the contents can be displayed in a variety of data formats. You don't have to remember arcane debugger commands--they're a choice on a menu. You can easily test a problem program because the high-level debugger presents it in the programming language you wrote it in. Typical high-level debuggers are Metrowerks' MW Debug and Symantec Think C's Think Debugger.
The downside to high-level debuggers is that, since they make heavy use of the operating system, they're only as stable as the operating system itself. A program bug that mangles the Mac OS often takes out the high-level debugger as well. And such debuggers cannot be used to debug code that exists on the fringes of the operati
ng system, such as drivers or Extensions.
In a Class by Itself
What category does The Debugger belong to? Both. It's a low-level debugger in that you can display the errant program's code as 680x0 or PowerPC machine instructions and examine the processor registers, the program's heap and stack, and any section of memory. But it also sports a boatload of high-level features. It has menus that let you point and shoot numerous debugger commands. Separate draggable Mac windows supply displays of the heap, the stack, and any Mac OS data structure you select. You view the code of the active (or current) function and can examine the contents of its local variables. If you compile your program so that special symbolic debugging information is available to The Debugger, it shows the program as source code.
With all these high-level features, you'd expect The Debugger to have the vulnerability of other high-level debuggers, but appearances are misleading. At boot time, The Debugger has two Extension fi
les that copy the device driver tables, trap tables, and system resources that it uses to implement the high-level interface into a private section of memory. It then uses this clone of system resources as it runs. Thus The Debugger can present a high-level interface to the programmer but has the immunity of a low-level debugger to all but the most severe system crashes. Steve Jasik definitely knows his way around the Mac OS, because this technical feat required some serious rocket science. Also, because The Debugger runs independently of the operating system, you can use it to debug system code, drivers, MDEFs, Extensions, and other exotic code fare.
Bug Hunt
As I mentioned, The Debugger works on 680x0- and PowerPC-based Macs. Like Macsbug, it's composed mostly of 680x0 code that runs in the 68LC040 emulator. The software fits on a single high-density floppy disk. On the disk are The Debugger, which weighs in at a mere 400 KB; MacNosy, a 680x0 disassembler that understands Mac traps and code resour
ces; and CoverTest, a code-execution profile utility. Two slim manuals, a quick reference card, and a sheaf of printed technical notes accompany the disk.
I used The Debugger on a Quadra 800 and a Power Mac 8100/80. You install The Debugger by copying the contents of the floppy disk to your hard disk. Next, you drop the Extension files into the System Folder and reboot. A supplied MPW script automatically performs the installation and resolves some Extension conflicts, but if you're using Think C or Metrowerks CodeWarrior, you're stuck with the manual installation. The Debugger can be configured to work on a second monitor, so that the other monitor is available to operate the problem program.
You call up The Debugger at any time by typing Option-\. Of course, The Debugger also seizes control any time an exception occurs. In either case, a distinctive green menu bar appears instead of the Apple menu. The Debugger menu bar shows how much remaining memory it has to work with, and at the far right
is the program counter's location. Also present are windows that display the offending function, the stack, and the PowerPC processor's registers. If the program crashes in the emulator or a function written in 680x0 code, 680x0 processor instructions and registers are displayed instead--an essential feature on a computer whose operating system is a mix of PowerPC and 680x0 code.
If you have generated a symbols file (.SYM for 680x0 programs and .xSYM for PowerPC programs) using MPW C or Metrowerks CodeWarrior, The Debugger loads this information and presents the function as source code, as shown in the screen on page 159. Local and global program variables are displayed and updated in a separate window. The Debugger can also obtain some symbol information from Think C 7.0 project files, but the display is limited mainly to source code: There are no names associated with the displayed local variables and no data types for both local and global variables.
In the source code window, you set breakpo
ints by just pointing and clicking: You highlight the source code statement of interest (executable statements are marked with a Epsilon) and then type Command-B or choose Toggle | Set Bkpt at from the Stops menu. You can select a function or variable to display by highlighting it and selecting Code | Data blk from the Display menu or by typing Command-D. For example, you can click on a function name that appears in the source code window, highlight it, and type Command-D, and the function's source code will appear in a new window. If you haven't selected a function, a dialog box prompts you for a function name. This lets you examine functions that might not be available in the current source window.
If you hold down the Command key and click on the source code window, its contents appear as source code lines interspersed with the machine code that implements the source line. For PowerPC code, a ``training wheels'' feature automatically comments the machine instructions; this is handy in aiding your un
derstanding of the PowerPC instruction set.
You can single-step through the program as source code statements or by each machine instruction. On PowerPC branch instructions, as you step through the machine code, The Debugger informs you whether the branch was taken or execution fell through to the next instruction. A Step Continuous menu item lets you set the rate at which The Debugger automatically steps through the program. This lets you feed the program events and watch how the code responds until it crashes.
A CFM (code fragment manager) menu item in the Tables menu lets you explore code fragments. By default, a window displays all of the program's code fragments, including the shared libraries associated with the program. As with all other debugger windows, you can highlight an address in this window and display it. This enables you to ``spelunk'' through shared library code or examine transition vectors, which describe the linkages between your program and shared library functions. This fe
ature alone should minimize some of the headaches that occur when programming the Power Mac run-time architecture.
Improvements Coming
The Debugger's most serious limitation is its documentation. The technical information sprawls across the entire range and history of the Mac, mentioning peculiarities in the Mac Plus, SE, and II as well as more recent machines. Most of this old material should be pruned. Worse, there's little PowerPC-specific material. Luckily, since The Debugger uses the same interface no matter what processor is driving the Mac, some of the PowerPC capabilities can be inferred from documented 680x0 features. However, not all of the 680x0 features are currently implemented in the PowerPC, and there's no description of the PowerPC-specific CFM item at all.
Jasik Designs has a revision of the major documentation in the works. By the time you read this, the new documentation will be distributed along with The Debugger on a CD-ROM. Buyers of The Debugger also get free periodic u
pdates of the product for a year, so users can expect these missing PowerPC features to appear in The Debugger as the year progresses. In addition, MacNosy should be able to disassemble PowerPC code this fall.
Despite the minor shortcomings, The Debugger provides ample PowerPC-specific support that reduces the debugging efforts of anyone writing native Power Mac code, regardless of whether it's an application, a shared library, an Extension, or a plug-in module. The Debugger's ability to display and debug two different processor instruction sets simultaneously is an extraordinary piece of programming. Its high-level source code display, combined with the ability to examine the program as low-level machine code, makes program tracing easy and the detection of obscure program bugs practical. The documentation could use some work, but serious programmers who are used to ferreting out information won't see this as a problem. The Debugger is thus the program for serious Power Mac development.
T
he Facts
The Debugger V2 $350
Jasik Designs
343 Trenton Way
Menlo Park, CA 94025
(415) 322-1386
Internet: MacNosy@NetCom.Com
Illustration: The Debugger displaying a PowerPC program as source code. The sigma symbols indicate executable statements. The bulleted source line has a breakpoint set on it, and the highlighting shows that the program execution has stopped on the breakpoint.
Tom Thompson is a BYTE senior technical editor at large. He is an Associate Apple Developer and author of Power Macintosh Programming Starter Kit (Hayden Books, 1994). You can contact him on AppleLink as T.THOMPSON or on the Internet or BIX at
tom_thompson@bix.com
.