MacCyclopedia: MacsBug for Non-Programmers

Reprinted from the 1998.03.09 and 1998.03.16 issues of MWJ, the Weekly Journal for Serious Macintosh Users.

Copyright © 1998, GCSF Incorporated. All rights reserved.

Note: This was originally a two-part series in MWJ in March 1998. However, between the release of the two parts, Apple released a new version of MacsBug. Therefore, Part I discusses only MacsBug 6.5.4a3, and Part II has "breaking news" about MacsBug 6.5.4a4.

Part I (from MWJ 1998.03.09)

Playing Cool Games With Dangerous Toys

Although the audience can be fickle at times, software publishers know that, next to games, there's no program all computer users love as much as a good utility. Even though computers do a decent job of assuming our workload in repetitive tasks, there is still plenty that can be done to make them friendlier, and Apple isn't going to build every possible diagnostic or enhancement tool into the shrink-wrapped Mac OS packages. That leaves plenty of room for Qualcomm (current owners of Now Software), Symantec, MicroMat (makers of TechTool) and others to strut their stuff for your hard-earned dollars.

But computers are a strange sliding scale. The easier a task appears to the user, the more complicated it is for the programmer. Software developers have very easy tasks in operating systems like UNIX, where everything is based on a command line and they're free to invent whatever twisted user interface fits their particular fancy, or mood, or mental illness on that day. Systems like the Mac OS enforce a consistent user interface and high user expectations, meaning developers have to work harder--significantly harder--to make their code match what you expect to see.

The more complex tasks become behind the scenes, the more obstreperous the tools the manage them become to use. As any utility moves more towards general purposes, it gains power but loses its ability to help you easily perform specific tasks. For example, screenplay-writing software makes it easy to format your documents in the precise style required by filmmakers and production companies. A more general word processor like Microsoft Word or Nisus Writer can do the same task, but they don't come with the code to walk you through the process. A drawing program can make pie charts as well as Excel, but it won't turn raw numbers into your chart for you--you'll have to draw the arcs and circles and pick the colors yourself. Some integrated programs can create drawings from spreadsheets, but modifying the chart requires either regular drawing skills, or modifying spreadsheet numbers and starting over. In general, the more powerful the tool is, the less helpful it is on specific tasks.

If you follow this line of reasoning to a logical extreme, you arrive at MacsBug.

Originally an abbreviation for "Motorola Advanced Computer System Debugger," MacsBug is today a powerful Mac OS only tool for debugging programs and digging into the lowest levels of the operating system underneath that six-colored fruit logo. MacsBug is described, quite truthfully, as a programmer's tool--its mysteries are not for the uninitiated, and its powers are such that if used incorrectly, you can screw up your computer to the point of having to restart. (You can screw up your disks, too, but that's usually a bit harder to accomplish, although you ought to be aware of it.) It is designed and aimed at helping programmers manipulate and analyze the code and data of their programs, to help them find and eliminate bugs. To this end, it lets you into the deepest and darkest recesses of the system, the places that have no user interface of any kind because they're not user-level domain.

That's why, if properly used, MacsBug can also give you information about problems like no other tool. While most of the built-in functionality is very strictly aimed at programmers, many of the external commands added in recent years can, in some cases, provide you with information that just might help you solve some crashing problems, or figure out what in the Sam Hill is going on, even if your programming skills don't extend beyond a cursory knowledge of AppleScript.

In this entry, we'll try to give you some basics about MacsBug, show you why it's useful to have around even if you're not a programmer, and reveal some of the hidden mysteries of the debugger that might lead you closer to nerdvana, if this is where you want to go today. First up is how to get it and where to put it (on your disk, that is).

Obtaining and Installing MacsBug

MacsBug is free for the asking from Apple's software archives, in the "Utilities" section. Like most Apple software distributed online, MacsBug now comes as a Disk Copy disk image. Unlike most Apple software of more than a few files, there's no installer. MacsBug is for programmers; the authors (who work on it in their spare time--Apple rarely has full-time engineers working on MacsBug) expect you to figure out how to install things from the instructions they provide.

However, that's not the latest release. The current version, released last April (MDJ 1997.05.01), is not MacsBug 6.5.3 but MacsBug 6.5.4a3, so designated because there is no formal testing for it and it can't easily be declared non-alpha any other way. But it works. To keep the uninitiated from easily finding it, Apple hides it away on the developer server. However, if you're paying attention, Apple's "MacsBug Version Information" file in the same folder as MacsBug 6.5.3 tells you where to find the "alpha" version, if you bother to look inside the file. Unlike the user-level distribution, MacsBug 6.5.4a3 is just a StuffIt archive with some files in it.

When you've got the unpacked MacsBug 6.5.4a3 distribution, you'll find a comprehensive "Read Me" file with changes since the 6.5.3 release, plus five folders full of other files. The "Building_dcmds" folder is for programmers writing their own additions to MacsBug and won't concern us. The "Into_System_Folder" directory contains MacsBug itself, and it goes at the top level of your System Folder (the same folder that houses your "System" and "Finder" files, if you have it buried a few levels deep as some people do). Older versions of MacsBug use a "Debugger Prefs" file containing external commands and preference resources--since changing it requires a resource editor, it comes with the creator type of ResEdit so double-clicking it will open Apple's free resource editor. The "Debugger Prefs" file has to be at the top level of your System Folder as well, but now MacsBug can load resources from up to 32 separate files of any kind found in the "MacsBug Preferences" folder inside your System folder. The distribution hints that it ought to go in the Preferences folder, but it can actually go there or in the Preferences folder--in fact, MacsBug seems to create a "MacsBug Preferences" folder in the Preferences folder if one isn't there. Apple does not define which of these preferences folders is examined first.

The "Into_Debugger_Prefs_file" folder contains a 'kchr' resource you can copy into your Debugger Prefs file, if you have one. MacsBug formerly came with a fully-loaded Debugger Prefs file, but in recent releases all of its goodies have moved into the MacsBug file itself. That leaves Debugger Prefs totally as your own file, and you don't have to worry about copying your resources out of it and into a new version when Apple updates MacsBug. The 'kchr' resource is necessary for MacsBug to take keyboard input--US users don't need it, but non-US users might not have the require US 'kchr" resource, so Apple supplies it. It has to go in the "Debugger Prefs" file; other files won't do.

The "Book_Example" folder is for examples and tutorial information from Apple's old official manual, MacsBug Reference and Debugging Guide. It's a decent programmer-level tutorial, and is official documentation for 1991-level MacsBug 6.2, but it's not as good about teaching programmers how to debug software. For that, you want Debugging Macintosh Software with MacsBug by Konstantin Othmer and Jim Strauss, who debugged more stuff than you really want to know about. Since the first book is Apple's official manual, the MacsBug distribution still carries the supporting files for the book, in case the accompanying disk ever gets updated, but don't hold your breath. Unless you have the book, you can safely ignore this folder as well.

Once you have all the files in place, restart your system. Note that on the "Welcome to Mac OS" screen, in the same place you would see "Extensions Disabled" if you held down the "Shift" key, is the text "Debugger Installed." That's how you know it's in the right place. If you hold down the Control key during startup, you'll enter MacsBug as soon as it's loaded. This probably isn't what you want, so don't do that right now. If you do, you'll need to figure out how to get out of it, and that's next.

Navigating MacsBug

Normally, you'll enter MacsBug in one of a few very defined ways:

  • By holding down the Control key as it loads at startup time

  • When a program crashes (or, more specifically, when the Mac OS calls its built-in "SysError" routine to draw the "bomb box" normally associated with a crash)

  • When a program specifically activates the debugger through commands called "user breaks"

  • By holding down the Command key and pressing the Power key

  • By pressing the hardware "programmer's switch" on older Macintosh models that come with such items. Usually there are two switches--one is a hardware rebooting switch and has the same triangular symbol as the Power key on the keyboard, and the other one has a broken squiggly line in it. The squiggly switch is the programmer's switch. Most recent Macintosh models don't have them, and the early 1990 models often made them optional. The classic Quadra 800 case has them right in the front in one of the most visible examples of these switches.

Once you enter MacsBug, you'll see a bewildering array of information. MacsBug wants 640 X 480 pixels to display its technical wisdom, but it will manage with 640 X 400 if that's all your screen supports (as is the case with some models). If your screen is already running at the lowest bit-depth that your system supports, you'll see MacsBug's display centered in the middle of your normal desktop--if your screen is larger than MacsBug's display. If your screen is larger but you're running at a higher bit-depth, MacsBug shifts your video drivers into low gear and forces the lowest possible bit-depth, so outside MacsBug's rectangle you'll see some distorted or expanded view of your normal screen. Ignore it if you can.

The very bottom line of this text window is the command line, where you type commands to MacsBug. It's a programmer-level tool--don't even think about using the mouse, because MacsBug does not and never has supported it. The left side of the screen shows the microprocessor registers. If you're on a 68K machine or running emulated 68K code, you'll see eight registers starting with "D" and eight starting with "A". PowerPC native code shows thirty-two registers, from R0 through R31 (with special names for R1 and R2). Ignore all this stuff--programmers use it to see what's going on, since registers are the heart of a microprocessor, but you won't care as a non-programmer.

At the top of the left-hand column is something the microprocessor calls a stack. Think of it like a stack of dishes in a cafeteria, because that's the heritage of the name--you can add more dishes to the top of the stack, and take any number off the top, but you can't take anything out of the middle of the stack without first taking care of the dishes above the one you want. The stack is really just an area of memory. Every time something is pushed on it, the stack pointer decreases a little bit. When something is pulled off the stack, the stack pointer increases a bit, always pointing to the "top" of the stack in memory. Each program's stack is at the very high end of the memory partition you've allocated for it in the "Get Info" box in the Finder. The stack grows downward from the top (it's like an upside down stack), and if it ever grows so big that it expands out of its normal space, it's a "stack overflow." That's a fatal system error if the system can catch it. You'll mostly ignore the stack, too, although it can be useful in a few ways that we'll explore later.

Between the stack at the top left and the registers at the bottom left is the phrase "CurApName," a global location in Macintosh memory that stores the name of the "current" application. Recall that the Mac's multitasking system works by passing control around to programs when waiting for you to do something. If you're not keeping up with the computer--and you probably aren't--the Mac OS will give another program some of the processor's attention until you do something. This is how other programs keep downloads going, clocks running, animations animating and so forth, even when they're not in front. So even if Netscape Communicator is frontmost when you enter MacsBug, it's CurApName that shows you which program is really in control. Watch that label carefully or you won't know where you are in the system.

The rest of the MacsBug screen is a scrolling log of the results of your commands. You can scroll through it with the up and down arrow keys, or page through it by holding down the Command key while using the up and down arrow keys, or by using the paging keys on an extended keyboard. Typing "help" or pressing the "Help" key on an extended keyboard will show the beginning of MacsBug's built-in help; pressing Return will cycle through all the help topics one by one. Just so you know.

You should also know that while you're in MacsBug, interrupt signals on your Macintosh are temporarily halted. The Mac uses interrupts--hardware signals that a device needs attention--to handle everything from mouse movements to high-speed Internet activity. As long as you're in the debugger, all of those signals go ignored. That's not good news--file servers and Internet protocols will time out after a couple of minutes, so don't try extended MacsBug sessions while connected to a network. (If you're connected to an AppleShare file server, you can type "stopxpp" to stop all sessions of XPP, an AppleTalk protocol. This disconnects you from all file servers, but it does so in a way that keeps programs from locking up your computer for two minutes waiting for a long overdue response.)

If you're on a normal dial-up Internet connection, you won't want to stay in MacsBug too long if you can avoid it, or the line might drop. To return control from MacsBug to the Mac OS, exactly where you interrupted it, type "G" and return. You can also press Command-G as a shortcut to "go" back to the Mac OS. There's a macro command "GG" that clears out all breakpoints and returns to the Mac OS; some people like to type that just to make sure they won't come back in accidentally. It won't hurt, but it's not necessary here. Don't get confused and hit the "Esc" key--that temporarily toggles display of the graphical user interface, but you're still in MacsBug! Press "Esc" again to see the text display.

Basic MacsBug for Non-Programmers

Now that you can enter and exit MacsBug at will, let's talk about some useful things.

Crash Recovery

When MacsBug is installed, all crashes make you enter the debugger. Instead of a graphical "bomb box" or even a vanishing program with a cryptic "unexpectedly quit" message, you get dropped right into the debugger at exactly the point where the system realized something was wrong. What's more, you get a more complete explanation of the problem, such as "Illegal instruction" at some address in some data space with other details you don't care about. The lines at the bottom just above the command line are the machine-level instructions right where the problem was discovered; the one with a "*" by it is somewhere near the current instruction (the one that couldn't complete), but emulation and bus timing concerns sometimes make MacsBug unable to pinpoint the exact instruction that triggered the problem.

Long-time subscribers can check MacCyclopedia in MDJ 1997.03.06 for a complete explanation of all the system errors and what typically causes them (such detail is beyond the scope of this article). With MacsBug, you always know what happened, and by examining CurApName, you're pretty sure about which program was "in control." What CurApName cannot tell you is whose code caused the problem. Extensions, control panels, components, and anything else that's not an application won't show up in CurApName, and neither will large components of the system software (the Finder, being an application, is a notable exception). Consider CurApName a hint about what's going wrong, but not a way to assign blame.

Programmers are expected to use MacsBug's capabilities to find and hopefully fix their problems. It's highly unlikely that you can fix a program you didn't write, even if you are a programmer, but MacsBug has a handy command for this. "ES" stands for "ExitToShell," the Mac OS routine called to tear down every application when it's finished. When an application "unexpectedly quits," the system calls ExitToShell on it while it's still running, disposing of all its memory and cleaning up after it as best it can. Sometimes the system doesn't give you the option of ExitToShell--it just shows you the "System Error" dialog box and forces you to restart. MacsBug always lets you try "ES". If it works, you may be able to save work in other programs before restarting. If it doesn't, you're still crashed, but it was worth a shot. If "ES" doesn't work, then "unexpectedly quitting" wouldn't have worked either, so you're no worse off. And in some cases, you're much better off. "ES" is much like pressing Command-Option-Esc in System 7 or later, but since it's part of MacsBug, it works even if you crash.

Note that Norton CrashGuard tries to do some of this same work, but it's only available as part of Norton Utilities 3.5 and only works on PowerPC machines. MacsBug is free and was invented for the 68K series of processors. Also note that "ES" always kills the program whose name is shown in CurApName--like Command-Option-Esc, it's easy to accidentally quit the wrong program if you're not paying attention.

Faster Restarting

If "ES" doesn't work, there are a few other commands. "RS" stands for "restart," but it's not the same kind of "Restart" the Finder offers. The Finder's "Restart" command (the same one you get when you press the Power key and choose the "Restart" button) sends an Apple event to all programs, asking them to quit, and then turns off the hardware only when the Finder is all that's left. The MacsBug "RS" command tries to unmount all of your online volumes and then toggles the hardware power, so you'll lose any unsaved work in any application. The main advantage to "RS" over hitting the physical power switch is disk unmounting. If a disk isn't unmounted correctly, the Mac OS realizes that something's wrong and goes through a time-consuming verification cycle next time the disk is mounted (made available for use). "RS" gives you a shot at unmounting the disks before restarting, saving some time. If that fails, "RB" tries to unmount only the boot volume before telling the hardware to restart. Either is better than simply pressing the power switch twice.

Helping Programmers Debug

If you crash someplace often, MacsBug is the tool to help programmers find out what's going on. And in recent releases, gathering the information is just about as easy as you could hope. MacsBug has a few expansion features. Macros are abbreviations for sequences of other commands. For example, the "GG" command is really a macro that expands into commands to clear all breakpoints and go back to the Mac OS. Type "help GG" in MacsBug to see--help on any macro gives you its full definition.

When you crash, especially in repeatable circumstances, the macro you want is "StdLog". It's short for "standard log," and it records a text file on disk containing the most essential information about your computer at the time it crashed. What the microprocessor was doing, what it thought was going on, whether or not memory was obviously trashed, what files were open, and much more. You can see it all whiz by as it happens. StdLog uses the "log" command to write MacsBug's output to a text file on disk; by default, it writes to a file named "StdLog" in the desktop folder of your hard disk. You can specify another place by using the "StdLogInto" macro followed by a full pathname (that's a text string with all the folders on the way to the file you want, like "Hard Disk:System Folder:Preferences Folder:My log file"). In fact, "StdLog" is just a macro for "StdLogInto StdLog," since file names without pathnames in front of them go to the desktop folder of your startup disk.

The file that StdLog and StdLogInto produce is more information about a crash than most programmers receive with most bug reports. MacsBug also supports "names" for code--programmers can build their programs so that each routine they write has the routine name embedded in the code at the end of the routine. MacsBug uses this to tell programmers exactly where things go wrong, as in "Bus error at DrawIconInWindow+0073", meaning 115 bytes (0x73 in hexadecimal, MacsBug's default number system) into the routine "DrawIconInWindow." The log file will record these kinds of things if they're present, and that will help programmers find problems a lot more easily.

Just be careful--repeating the "StdLog" command twice without removing the first "StdLog" file will make MacsBug append the new log to the old one, leaving just one file. The log files are just plain text files with the MPW Shell creator type--MacsBug was designed for programmers, so double-clicking the logs opens Apple's own programmer's environment.

Working With Numbers

MacsBug also makes a quick integer calculator, if you know what you're doing. Remember that the default number system is hexadecimal, with digits 0-F (representing decimal numbers 0-15), and that each place value is the digit times sixteen, not the digit times ten. In decimal, "34" means (3*10)+4, for thirty-four. In hexadecimal, "3F" means (3*16)+15, or sixty-three (decimal). If you pop into MacsBug and type "34+10", you'll get "44", but only because the digits work out the same in hexadecimal for those cases. Typing "34+9" gets you "3D". To tell MacsBug to treat a number as decimal ("normal") instead of hexadecimal, put a "#" symbol in front of it. #34+#9 does equal #43, or $2B (the "$" is an old prefix meaning hexadecimal notation).

MacsBug also knows about the memory and disk space modifiers "K", "M" and "G". 1K is the same as 1024, since a kilobyte is 1024 bytes. If you need to know how many K are in 200MB for some reason, enter MacsBug and type "#200M/#1K", and you get back a result that ends with "exactly #200K," which isn't that surprising. Type "help operators" in MacsBug to see a list of mathematical and boolean operations that work--your basic four functions plus some bitwise operators that programmers need to mess with individual bits, and a few other gems you'll generally never use.

Working With System Information

More important than numbers is system information, especially if you're trying to solve a problem. MacsBug has a wealth of information about what's going on under that graphical interface, just waiting for you to ask.

A classic example--an MWJ staff member was trying to launch a 12th program on a large machine when everything started quietly failing. Some programs would give error "-42", but he couldn't get a "System Errors" program open to tell him what it was. MacsBug to the rescue! Entering the debugger and typing "error #-42" (remember, decimal numbers must start with "#") spits back a string that says "tmfoErr--too many files open." You may not know the Mac OS is limited to 343 open files at once.

"But how so I know what files are open?" cried the staffer. "I only have a couple of documents open. What's the deal?" MacsBug strikes again! An external command named "file" lists information about every open file on the system. After scrolling through a few pages of the list, it became obvious that the staff member had inadvertently opened a lot of font suitcases with Adobe Type Manager Deluxe--and we mean a lot, as in about 75 of them. When factoring in files that the system keeps open for itself (catalog and extents trees on HFS and HFS Plus volumes, Finder Preferences, Desktop database files on each volume), plus BBEdit plug-ins, Acrobat Exchange plug-ins, WebArranger plug-ins, Internet Explorer plug-ins, shared libraries, extension files, extension preference files, application data forks (for PowerPC code), application resource forks (for interface resources--and each fork counts as a separate file)--no wonder it ran out of space! A quick look in MacsBug helped him figure out what he could do (he asked ATM Deluxe to close about 60 of the unused font files) and that helped tremendously.

Of course, half the battle is knowing what MacsBug can do. Some of the useful information comes from built-in commands, but much of it comes from dcmds. Like HyperCard's "XCMD"s, dcmds are "debugger commands," written by programmers and dropped into MacsBug's lap by adding their resources to the Debugger Prefs file--or to one of the first 32 files in the MacsBug Preferences folder. "File" is a dcmd, and it's quite useful in areas like the extant case. Some useful dcmds for non-programmers include:

  • "File", as mentioned, displays information about open files. You can restrict the display to files of a given name or type with options (type "help file" to see how). Every time a file is opened, it returns a reference number that the system uses when operating on the open file. "File" displays reference numbers in hexadecimal, but simply typing the number as a command will show you the decimal equivalent. This can come in handy for people working with the file access commands in AppleScript. If your script opens a file but stops before it closes that same file, the system leaves the file open until the application that called the script quits--and depending on how the script executed, that might not be so easy to arrange. The "File" command can show you the reference number of a file you left dangling in a script you're testing. Let's say the number is 7F34. You type "7F34" on the command line and get the decimal number 32564 in return. That's the reference number. The AppleScript statement "close access 32564" closes the file for you, so your script can open it next time without getting a "file already open" error.

  • "VMDump" normally displays a lot of information about which parts of RAM are handled in various ways by virtual memory, and you're extremely likely not to care. However, adding the "-f" flag (as in "VMDump -f") forces the dcmd to give you a list of all file-mapped files. File mapping reads the file itself as the swap file, instead of reading the contents into RAM and swapping it with the major "VM Storage" file on disk. These are the files that will require more memory if you turn VM off.

  • "RD" shows you the current resource chain. When a program requests a resource from a file, the programmer has the option of telling the system to stop if the resource isn't in the last resource file opened. In most cases, though, the system keeps looking through all of the open resource files, from the most recently opened to the least recently opened, stopping only when it reaches the bottom of the chain (typically the System file itself) or the resource is found. This is how programs can override default behaviors--by providing a custom control definition procedure resource, for example, the programmer can act just like he's using regular simple buttons. When it's time to use them, the system looks for the right 'cdef' resource, and if it happens to find it in the application's resource fork before getting to the System file, so much the better.

    The Mac OS does some Serious Voodoo Magic to make all the files in your Fonts folder look like they're part of the System file to the Resource Manager, so "RD" has an option to skip them. The command, which stands for "resource dump," displays information about resources in open files unless you specify the "-c" option, as in "RD -c", to show just the resource chain. "RD -s" does the short form, leaving out all the font files in your Fonts folder. If you're getting a "resource not found" error (#-192), "RD" can help you figure out where the system is trying to find the resource. This helped us recently figure out that an extension was responsible for a printing problem.

  • "Vol" lists all online volumes (disks), if you think one is not available but should be or vice-versa. "Vol" can't fix problems, but it can let you know if the OS is aware of a disk or not. Each volume is listed with a "d" flag for whether the volume is "dirty" or not (has blocks in the cache that need to be written to disk before the disk is unmounted), "s" for software locked, or "h" for hardware locked (like a write-protect tab on a floppy disk). Capital letters mean the attribute is true, lowercase letters mean it's false.

  • "ProcInfo" shows you all the current processes, with flags indicating which one is the front process (different from the one listed in CurApName, perhaps), which ones are background-only, and so forth, A "free" column shows how many free bytes are in each process's memory partition, so if a program says it's running out of memory, you can see which programs are using the least memory and perhaps reduce their partitions for the future. User-level utilities can sometimes do this as well, but MacsBug is handy.

  • "Gestalt" is a dcmd that displays the return values of all "Gestalt" selectors. Gestalt is a Mac OS mechanism programs can use to register values that any other program can find. For example, Suitcase 2.0 and later register a Gestalt selector that points to a single two-byte value in memory. Every time Suitcase opens or closes a font, it increments the two-byte value. Suitcase aware programs can call Gestalt to find the value of this location and watch it. When the programs become frontmost, they can examine the value--if it's changed, it's time to rebuild the font menu. The Mac OS registers approximately six googol and three Gestalt selectors to tell programmers what features are present, what versions of system software are available, what bugs are fixed and what programmer initials are. The "Gestalt" dcmd doesn't explain what all the selectors mean, but it shows you some meanings and lets you see all the values. It's more educational than useful, but that's true about the Internet, too.

Practice Your Basic Skills

While this is a long way from everything MacsBug will do, it should be enough to let you play around and learn all kinds of stuff about your system. Note that MacsBug does require a bit of memory (at least a megabyte). Also, try not to change any values if you can avoid it--just look at them unless you're absolutely sure of what you're doing. Programmer toys can be dangerous if not used properly.

Part II (from MWJ 1998.03.16)

Poking Around Memory and Other Dangerous Hobbies

In Part I, we discussed how to find the latest version of MacsBug, how to install it, what the various preferences files meant, how to use it for elementary crash recovery beyond what the system normally allows, and how to use external debugger commands to poke around open files, the resource chain, and other programmer-related arcana that sometimes affect your use of the system.

In this conclusion, we'll examine the memory structure of the Macintosh, including what applications are really doing with those megabytes of memory you allocate to them in the Finder's "Get Info" dialog box, with plenty of warnings about how a little learning is a dangerous thing. But first, we have breaking news that could make these specific kinds of exploration much simpler.

Remember, however, that MacsBug is a programmer's tool. That means it deals with rather technical concepts, and has a user interface only a programmer could love (or even tolerate). For example, to configure MacsBug, you have to edit resources (with ResEdit or Resorcerer). Some resources, like those for external commands, can be in MacsBug, or in the "Debugger Prefs" file located in the System Folder, or in any of the first 32 files (listed by name) in the "MacsBug Preferences" folder in the Preferences folder. There are other kinds of resources that configure internal MacsBug parameters (instead of adding new capabilities), and there can only be one of each kind of those resources (like 'mxpr' for MacsBug preferences, 'mxbc' for MacsBug colors, plus others). MacsBug itself has one of each of these resources, but you should leave them alone. If you want to edit them, copy them and paste them into your copy of the "Debugger Prefs" file. MacsBug won't even look for these kinds of resources in the "MacsBug Preferences" folder.

Stop The Presses: MacsBug 6.5.4a4

After a few weeks of trying to get it out the door, Apple Computer last week finally released MacsBug 6.5.4a4, the first new release of the debugger in about a year. There was a newer version included with the "Blue Box" shipped to developers after the Rhapsody Developer Release 1 (MWJ 1997.11.24), but only those developers who actually have a Rhapsody DR1-capable machine could get to it, if they even noticed it--and it's probably just as well that they didn't, since it had a bug that could trash your hard disk if you pressed a key while MacsBug was writing to disk.

The new release comes with extensive change notes, but we want to cover a few of them here because they might affect non-programmers who have MacsBug installed:

  • MacsBug now uses color for displays. This is somewhat of a misnomer, because it doesn't use much color, and formerly it would use some color. The "Debugger Prefs" file could optionally contain one resource of type 'mxbc' specifying a single RGB color to use for text in MacsBug's rectangle, and another RGB color for the background color. That resource is now obsolete, and a more standard 'clut' (color look-up table) resource with four entries is now used. The first entry is the background color, the second is the text color, and the third is the "pay attention to this" color (pure red by default). The fourth color is the "pay a little attention to this" color, but MacsBug 6.5.4a4 doesn't use this color. The primary use of color in this release is in the register display along the left-hand side of the display--when programmers step through code, getting MacsBug to execute one instruction or one subroutine at a time, any registers that change during the execution are redrawn in red to bring them to your attention. When you first enter MacsBug, all of them will probably be red since the "previous" state is undefined.

    MacsBug still automatically switches your monitor to the lowest bit-depth it supports, which is one-bit color on all but the newest Power Macintosh systems. All MacsBug really needs is four colors, or two bits per pixel. However, if you play with ResEdit and examine the 'mxpr' resource in MacsBug itself (copy it into your "Debugger Prefs" file before modifying it, please), you'll find an option labeled "don't swap display bit depth." If you set this option, MacsBug will never shift your display into a different bit depth, meaning the MacsBug display pops up quite nicely in the middle of your "Happy Mac" screen without affecting the rest of the display. This is pretty cool, but MacsBug has to save and restore the area of the screen underneath its display. If you don't let it switch pixel depths, then MacsBug has to allocate enough memory to handle the pixels under its display at any supported bit depth. If you're running the MacsBug monitor in millions of colors, for example, MacsBug has to allocate four bytes for every pixel in 640 columns and 480 rows (1200K, or 1.2MB of RAM). That memory is lost to your system while MacsBug is installed. Unless you have a solid reason for wasting a megabyte of RAM, leave this alone. If you have this much RAM to waste, consider using or enlarging a RAM disk, since it's generally a more useful way to allocate memory.

    If you don't set this preference, though, MacsBug will still shift into black-and-white only mode if your system supports it, and that means you won't see the new red numbers in the display. You might want to play with both settings to decide which works better for you, particularly if you're a programmer who steps through code--that's where the red displays come in most handy.

  • If you've had MacsBug installed for a while, enter it and type "help leaks". If you're told that no command by that name is available, great. If you get help for a dcmd by "Bo3b Johnson" (the "3" is silent, you see), open your "Debugger Prefs" or "MacsBug Preferences" files until you find the 'dcmd' resource named "leaks", and remove it. Leaks is a tool that watches how memory is allocated, and it helps programmers figure out when a chunk of RAM is allocated but never released back to the system when the program is finished with it That's called a memory leak. The "leaks" command patches several Mac OS Memory Manager traps to do its work, and the code it inserts is 68K code. If you're using a PowerPC system, "leaks" could be unintentionally slowing down calls the system makes thousands of times per second, so ditch it. (If you know what leaks is and actually use it, consider keeping it in a separate file and rebooting when you need it to increase overall system performance.)

  • MacsBug now understands displays that turn themselves off automatically to save power, and will try to turn them back on when it gets control. In previous versions, a crash into MacsBug while the display was powered off left you with a black screen--and no way to turn it on, since the Mac OS software responsible for waking up your monitor couldn't get control while MacsBug was active. This is now improved.

  • The "RS" and "RB" commands discussed in Part I are a bit more bare-bones in their execution. Programs on the Macintosh can ask the system to call them when it's time to shut down or restart the machine--a good example is Open Transport/PPP, which installs a shutdown "task" so it gets a chance to drop your PPP connection. In earlier versions, MacsBug would allow those tasks to execute during "RS" or "RB", but the system wasn't always in a state where such tasks could work properly, creating more crashes (or just plain lock-ups). Now MacsBug calls only the ROM-based Shutdown Manager, or tries to do so, to avoid these problems.

  • Keystrokes will no longer occasionally "leak" from MacsBug into the frontmost application.

  • The "StopXPP" dcmd mentioned last week is now renamed "StopAS," as in "Stop AppleShare." AppleShare connections can now be over TCP/IP as well as AppleTalk now, so "StopAS" closes AppleShare sessions on both transports. As noted last week, an AppleShare request that times out while you're in MacsBug can results in a two-minute lock-up after exiting when a program tries to access the server, which is disconnected except your machine doesn't know it. "StopXPP" is an alias for "StopAS," if you're already used to the old command.

  • Programmers can always count on MacsBug release notes for a shot or two of humor. Our favorite in this release: "The STAT command and SECONDS basic type now show the year as 4 digits instead of 2, making MacsBug year 2000-savvy. This saves the Macintosh industry approximately US$430 million per year, according to current US Department of Labor statistics." Use your savings to buy extra copies of MacsBug.

MacsBugApp

However, the most important change for our purposes in MacsBug 6.5.4a4 is the inclusion of "MacsBugApp," an application version of MacsBug that's been kicking around Apple for a while. Double-click MacsBugApp and you'll get a new application with a window containing MacsBug's familiar display. Type commands, look around, see registers display in red, and all your favorite commands. And since it's just a regular application, other programs continue to work as usual--file transfers aren't stopped, networking connections won't drop, and so forth.

Theoretically, MacsBugApp is a replacement for an older "TestDCMD" program. Developers creating debugger commands can now install them in MacsBugApp (its "Debugger Prefs" file has to stay in the same folder as MacsBugApp itself, as does the "MacsBug Preferences" folder), and use the real MacsBug to debug them in the middle of MacsBugApp.

For your purposes, though, MacsBugApp is a less dangerous way to poke around the system. Since it's an application and not a "real" debugger, MacsBugApp can't do things like step through code, but if you just want to look around the system, it's just fine. It won't help you in crash recovery--typing "ES" in MacsBugApp gives you the weird "System Error #0"--but all of the poking around the system we'll talk about this week works just fine from within MacsBugApp.

To demonstrate, take last week's example of "too many files open." Launch MacsBugApp (if you can) and type "file" to see a list of all open files. If you want to know which ones will be closed, use the "ProcInfo" dcmd first. That gives a list of all processes, including the system's "process serial number," a four-digit hexadecimal number listed in the first column. Let's say the program we want to test has a process serial number of 2008. Try typing "file -p 2008" to see a list of all files that were opened by the program with process serial number 2008. Quitting that program closes all those files. Now you know. (By the way, the "-p" option in "file" is new in MacsBug 6.5.4a4.)

We're advised that MacsBugApp has some problems if virtual memory is turned on, and our staff didn't find it to be without flakiness--sometimes the commands they typed disappeared as they typed them (white text on a white background, we suspect), and the staff saw a few strange crashes as well. If you want to use MacsBug for crash protection and other poking around, it's OK to install it and use the "real" MacsBug instead of MacsBugApp, especially if you have trouble. It's just nice to have choices.

With these preliminaries aside, let's get back to the fun stuff.

Partitioning Memory

You're probably familiar with the concept of partitioning large disk drives into smaller virtual "volumes." When you do this, even though all the volumes are stored on one device, every part of the Mac OS above the very-low-level SCSI Manager treats them as separate devices. A program that goes wacko and erases a "disk" can't erase the other partitions. More importantly, for HFS users, smaller volumes reduce the size of each volume's allocation block, saving disk space in the long run.

Whether you know it or not, the RAM in your machine is "partitioned" as well. You control how much RAM each program gets through the memory allocation in an application's "Get Info" box in the Finder. The numbers, as you may know, are actually stored in a 'SIZE' resource in each application's resource fork, which is how you can change them for programs like the Finder, or for extensions that spawn background processes but aren't applications themselves. As always, don't try this unless you're sure of what you're doing, or unless you have multiple duplicate (and redundant) backups.

To see the way the system has doled out your RAM, enter MacsBug or MacsBugApp and type "hz", for heap zones. A heap is the rough equivalent of a memory partition, with the notable exception that heaps can contain smaller, sub-heaps. (Disk partitions can't contain smaller disks, unless you think of something like a DiskCopy image as a "partition" even though it's just a file. Heaps can be more recursive than that.)

The list of heap zones, as they're sometimes called, is numbered for easier reference. The first one will probably be what's informally called the system heap, and is the area of memory where the Mac OS tries to allocate most of the RAM it needs for components, the operating system itself, and other fundamental memory-chewers. Inside the System Zone are other zones, probably unlabeled, although MacsBug does recognize one on some machine as the "ROM read-only zone," where parts of the ROM are made to look like a read-only heap zone. The indenting shows you the heap containment level--those listed to the right of the System Zone's line are contained within the system zone. The starting and ending addresses for these sub-heaps show that as well--all of them start and end within the System Zone's starting and ending addresses.

The application you were using when you broke into MacsBug (or MacsBugApp itself if using the application version) will probably be identified as the "ApplZone," meaning the zone for the current application. It's probably also listed as the "TheZone," meaning the target of current Memory Manager calls, and "TargetZone," meaning the heap zone that MacsBug will operate on by default. Want proof? Type "hx" and MacsBug responds that the target heap is now the System zone. Type "hz" again, and sure enough, "TargetZone" now appears next to the system heap (which should be heap #1 on all systems).

Why deal with all this arcana? MacsBug isn't a general-purpose memory profiling tool like Bob Fronabarger's Memory Mapper. Memory Mapper looks at the same kind of information as MacsBug and draws you a chart showing where each application is residing in RAM--but Memory Mapper also shows you free spaces. The "hz" command doesn't do that, unless you look at the ending address of each heap and compare it to the starting address of the next one. Memory Mapper makes explicit what MacsBug leaves as an exercise to the reader.

What MacsBug can do that Memory Mapper cannot is show you what's going on inside one of those application heaps. Launch an application that's very small--we suggest Note Pad. (We were going to suggest Calculator, but our staff tells us its heap is always damaged for some reason, something MacsBug can detect as we'll tell you shortly.) When in Note Pad, break into MacsBug (MacsBugApp won't do for this one, sorry). Make sure CurApName, on the middle left, says "Note Pad," but you can continue for a moment if it doesn't.

Type "hd" to dump the heap. You'll see a listing of every chunk of RAM allocated out of Note Pad's heap. Here's how the start of such a display might look as shown in Listing 1:

Displaying the "Note Pad" heap at 0738AA70
Start Length Tag Mstr Ptr Lock Prg Type ID File
Name
* 0738AAB0 00000044+00 N
* 0738AB00 00000100+04 N
* 0738AC10 000002C2+12 R 0738ABF4 L CODE 0004 6C54 Main
* 0738AEF0 00004334+10 R 0738ABF0 L CODE 0002 6C54 app
* 0738F240 00003E26+0E R 0738ABEC L CODE 0003 6C54 Other
* 07393080 00000242+12 R 0738ABE8 L CODE 0001 6C54
* 073932E0 000000BE+06 N
* 073933B0 00000014+10 N
* 073933E0 00000126+0E N
* 07393520 0000009C+18 N
* 073935E0 00000100+04 N
* 073936F0 0000009C+08 N
* 073937A0 00000100+04 N
* 073938B0 000006F9+0B N
  07393FD0 000002D4+00 F
  073942B0 000001EC+08 R 0738ABE0 PICT 0080 6C54 8 bit
  073945F0 0000001D+07 R 0738ABD4 CNTL 0081 6C54 Size
  07394620 0000001D+07 R 0738ABD0 CNTL 0080 6C54 Font
  07394650 0000000C+08 R 0738ABCC ALRT 0085 6C54 Error
  07394670 00000080+04 R 0738ABC8 P ICON 0080 6C54
  07394700 00000723+11 R 0738ABF8
  07394E40 000000A0+04 R 0738ABFC
  07394EF0 0000001B+09 R 0738ABC4 P WIND 0080 6C54
  07394F20 0000029F+15 R 0738ABC0 MENU 0080 6C54
  073951E0 00000015+0F R 0738ABA0 DLOG 0083 6C54 Delete

Listing 1 - Sample Heap Dump of Note Pad

The "Tag" field in the third column tells what kind of RAM chunk this is. Most memory is divided into relocatable chunks--through a bit of double-indirection, the Mac OS can move the contents of this block of RAM to a new location, but the program can still find it. Those blocks are tagged "R," for relocatable. Relocatable blocks can be temporarily locked so they can't move around for a while, and that's indicated in the sixth column, titled "Lock." For example, the third memory chunk in this list is relocatable but locked. That means the Memory Manager can't move it to a new location to find room in filling new memory allocation requests.

Filling requests for memory is what the Memory Manager is all about, and it goes to great lengths to jam requests as close together as possible while not spending millions of CPU cycles doing it. For example, blocks of memory as allocated are always a multiple of sixteen bytes to make things easier on the microprocessor. That's what the "+" in the length column means--each block is padded past the requested length to make things easier. For example, the third block in the list is 704 bytes long (0x2C2), and it's padded by eighteen extra bytes to get 722, which works better for this system. It doesn't like to pad by one or two bytes, possibly to help insure against memory trashing problems if a program writes one or two bytes beyond the end of a block (a common enough problem). In fact, the only blocks you see in the list with absolutely no padding are the first one, which contains the heap zone header, and one down the list with the tag "F", meaning it's free space and not allocated memory.

See the dots in the left hand column (represented as starson this Web page)? Those indicate blocks that can't move at all, or movable blocks that have been locked. When the Memory Manager gets a request that it can't fulfill, it tries to move blocks around to make things work. For example, suppose 500 bytes were free on one side of a relocatable 200-byte chunk of RAM, and 400 bytes were free on the other side of the same chunk. If the program then requested a 700-byte chunk of RAM, presuming this was all the free space available, the Memory Manager couldn't do it. However, if it swapped the relocatable 200-byte chunk with either of the free blocks, the two free blocks would merge into one larger 900-byte free space, and that's more than enough room to fill the request.

If the 200-byte allocated chunk had been locked, however, the Memory Manager would have been stuck. To prevent problems like this, programmers try to keep all of the unmoving blocks either at the very top or very bottom of the heap, leaving everything in the middle free to shuffle around as necessary. Locked blocks in the middle of the heap can permanently fragment it so that future allocations fail when room is really available. That, unsurprisingly, is why it's called fragmentation.

The "hd" command in MacsBug can show you how fragmented a given heap is. A programmer could use this information to try to reduce the fragmentation, but there's not much you can do except note that it's there. Well, maybe there are some things. In Listing 1, the rightmost columns are often filled with resource types, resource IDs, and file numbers for where resources came from. If you see a large number of resources associated with some plug-in module you can unload, you might be able to reduce memory usage and fragmentation, but that's a long shot. It's mostly informational, and if your heap is really fragmented, the information is "you're toast."

If CurApName did not read "Note Pad" when you broke into MacsBug, the heap you tried to dump was probably some other heap. Use the "hz" command to find Note Pad's heap by number (in the leftmost column). If it's number #13, for example, type "hx #13" to switch to it. Then try the "hd" command. You may be surprised to see a lot of "resource not found" identifiers on the right side instead of neat and precise listings of type and ID as shown in Listing 1. That's the cooperative multitasking of the Mac OS showing itself. The Mac OS application model was designed when the machine only ran one program at a time, so each program has certain properties that it thinks are global. One of those is the resource chain, or the list of open files where the system looks to find requested resources. Each application has its own chain--it wouldn't be appropriate for Note Pad's request for 'pict' resource 128 (0x80 in hexadecimal) to come up with that resource from Netscape Communicator if it happened to be open, so the system makes sure that Note Pad's resource chain is unaffected by other applications. Here you see the results--when dumping Note Pad's heap during another application's time (as shown by CurApName), Note Pad's resources aren't available, so MacsBug can't display their real type and ID values.

An easy way around that is to type the macro "WNE". This tells MacsBug to resume normal execution, but stop again the next time a program gives up control with the core system routine "WaitNextEvent." If Note Pad was frontmost when you entered MacsBug and yet it still wasn't listed in CurApName, the "WNE" macro will break again when Note Pad is in control. Pretty nifty. Using it repeatedly will typically cycle through programs on your system that are calling WaitNextEvent. That will typically catch all of the old-style 68K applications on your system. PowerPC code, or CFM-68K applications (MDJ 1997.12.02), use a newer style of Mac OS access called "transition vectors" instead. The "WNE" macro won't catch those, but you can define a PowerPC-style macro that will with the following command:

mc wnep "tvb WaitNextEvent '; tvc WaitNextEvent'; G; # reenter MacsBug on next WaitNextEvent transition vector call"

You'll have to include this in a MacsBug preferences file to get it to stick around permanently, and we'll discuss that later. Type "help WNE" if you want to see how similar this is to the existing "WNE" macro.

What Can You Do With This?

Examining heaps is typically a task for programmers, but you can glean a few things from the available commands if you're a reasonably technical user. Let's apply some of this knowledge to a practical situation.

Suppose a program you're heavily using is claiming no more memory is available, even though other tools (like "About This Computer") reveal plenty of allegedly free space. If you can get to that program's heap in MacsBug or MacsBugApp, the "ht" (heap total" command will quickly show you how many chunks of free space are available, and the total number of bytes in all those chunks. That will generally coincide with what other tools told you. However, looking at the dots on the left side of the "hd" display can show you if the heap is horribly fragmented or not. If it is, then closing documents or quitting and relaunching the program should give you a new lease on life. If it's not, there's not much you can do, but you do know one thing--adding more memory to the application in the Finder's "Get Info" window might not help. After all, if the application already has 5MB of free space, verified by MacsBug, bumping that to 10MB probably won't solve the problem. Use the "log" command in MacsBug to record the "hd" output--you can append it to the end of a "StdLog" file if you want--to help the programmers figure out what's going wrong on your system. It might not be sufficient information, but it's more than they'd have if you just wrote to the company and said "How come your stupid program doesn't work?"

If the program is behaving weirdly, try the "hc" command to check the heap. If a program has trashed memory in a way that the Memory Manager's data structures are no longer valid, "hc" will usually tell you. If you find your heap has been corrupted, tread very carefully. Save what work you can, but be aware that things could get worse as you save. Do as little as possible to preserve what's necessary before quitting the program, and consider restarting your system. The "hc all" command supposedly checks all heaps, but in our experience it tends to skip some of them. Note that memory can be trashed without affecting the heap structures, so "hc" won't definitively tell you if any corruption has occurred. But if "hc" in MacsBug 6.5.4a4 says something is damaged, it probably is. (Earlier versions sometimes listed special heap zones, like the ROM read-only zone, as damaged when they were just defined differently. MacsBug 6.5.4a4 is better at detecting such things.)

There's an exception here: If you broke into MacsBug in the middle of a Memory Manager call, "hc" may report a corrupted heap simply because the call needs to complete. Try the "WNE" or "WNEP" macros to regain control when things should be fine.

Processing Processes

If you just want to see a list of all running processes, you don't have to mess with heap zones. In MacsBug (or MacsBugApp), type "ProcInfo". This gives you a list of all currently running programs, or processes, on your system. The first few lines might look like this:

Displaying Process Information
PSN Process Name Size Free HeapAt Type Crtr Status

2003 Web Quick 000B2000 0003CAC0 07A15900 appe ANU! BgOnly
2005 Finder 000EC400 0006F5F0 0788CE00 FNDR MACS Bkgnd
2006 QuicKeys Toolbox 0004D800 0001C2A0 078252B0 INIT IACi BgOnly
2008 DragThing 2.1 00101000 00095B40 076DB800 APPL Dock Bkgnd
200A Desktop PrintMon. 00023170 0000C410 07699E70 APPL prmt BgOnly

Listing 2 - A Partial ProcInfo Production

The process serial numbers, or "PSN" column, aren't necessarily consecutive because you may have launched and quit some programs--or some might have launched and quit automatically. Of the five processes listed here, three of them are listed as "BgOnly," meaning they have no user interface whatsoever, and are sometimes called faceless background applications or FBAs. Web Quick's FBA receives Apple events from Web browsers as you surf the net, and communicates with the menu installed by the Web Quick extension to tell browsers where you want to go--only applications can send and receive Apple events, but an FBA is an application. QuicKeys Toolbox handles Apple event communication for CE Software's QuicKeys--you can see from the "Type" column that QuicKeys Toolbox is actually an extension, or 'INIT', and not a real application file. Desktop PrintMonitor communicates with the Finder to handle background printing. The Finder draws the windows and controls you see, but Desktop PrintMonitor tells the Finder what to draw.

The only semi-normal application in this list is DragThing 2.1, so it's what we'll examine. The "Size", "Free" and "HeapAt" columns discuss the state of DragThing's RAM allocation. All the numbers are in hexadecimal, as MacsBug prefers, but you can convert to decimal simply by typing them on the command line. If you do, you'll find that DragThing 2.1's memory starts at address 12,463,140, that it has 1,052,672 bytes allocated to it (which MacsBug dutifully reports as "just over 1M", meaning one megabyte), and of that allocation, 613,184 bytes ("between #598K and #599K") are free. DragThing looks to be in good shape on this system. In fact, looking at the program's bar in "About This Computer" would graphically show almost the same thing.

The display from "ProcInfo" is generally much less complete than that of "hz" or "hd", but it can give you all the information you need if you're not sure what's going on. And, as mentioned earlier, you can now use a process serial number like 2005 in the command "file -p 2005" to see what files that process (the Finder in Listing 2) has open.

More On Crash Recovery

If you're a bit more comfortable with MacsBug now, there are other ways you can use the debugger to help you during a crash. Here are some of our favorites.

Disabling User Breaks

You'll occasionally find software--especially beta-level software--that appears to crash with "Unimplemented Trap" instructions with the instructions "A9FF" or "ABFF". These are Mac OS system routines designed to invoke MacsBug, and if MacsBug isn't there to implement them, the traps (a special type of 68K instruction often used on the Mac to refer to system routines) aren't implemented. If MacsBug is present, you'll enter it with the notation "User break" at wherever the code was located. Trap A9FF is "Debugger" and just enters MacsBug. Trap "ABFF" is called "DebugStr", for "debugger string," and it displays a text message beneath the "user break" notice. You can see all these again later in any session by using the "HOW" command, which reminds you how you got into MacsBug in the first place.

User breaks are very handy for programmers. The microprocessor executes a few million instructions per second, and trying to press Command-Power exactly where you want to stop is a lost cause. Instead, developers insert these instructions into their code and stop exactly where they want to stop, so they can poke around and find problems and examine situations. It's all very cool, unless the programmers accidentally leave some of the MacsBug calls in a program shipped to customers. Even if you have MacsBug installed, you probably don't want the software to stop every so often with a message that means nothing to you.

Fortunately, you have an alternative. The "dx" command disables user breaks. It's a toggle, so entering MacsBug again and typing "dx" turns them back on. Or you can type "dx on" or "dx off", or the new "dx now" to see the current state. Once user breaks are disabled, any stray Debugger or DebugStr calls won't bother you until you explicitly turn them back on or restart. That should tide you over until the developers can fix the bug.

Finding Lost Data

This is significantly trickier, but it can save your bacon in extreme emergencies. What if you've just entered data that you can't replace and the system crashes? Even a successful "ES" will quit the program and you'll lose it. There is a small chance you can find it, if you can remember part of it. For an example, let's go back to Note Pad. Enter the phrase "bicarbonate of soda" on one page, and then enter MacsBug (or MacsBugApp if you're just playing around).

MacsBug has a "find" command that will search memory, but it's not overly-friendly. You must tell it where to start looking and how many bytes to search, in addition to the item you're trying to find. Use the "ht" command to get the total of Note Pad's heap. At the top, MacsBug will tell you that it's totalling the Note Pad heap "at" some address in hexadecimal. That's where to start. At the end of the "ht" display, an eight-digit hexadecimal number in the "total of block sizes" column gives the size of the heap. That's how many bytes to search. In our example, the Note Pad heap was at 0738AA70 (as shown at the top of Listing 1, too), and the heap size was 00031EFC bytes. You can convert these numbers to decimal to see what they're like, but it's not necessary.

We're ready to try it. Suppose you can remember that the text you lost had something to do with "carbon." Our sample would use this command, plugging in the Note Pad starting values and size:

F 0738AA70 00031EFC 'carbon'

Listing 3 - Sample Find command

The leading zeroes on numbers aren't necessary; they just make the values look like what MacsBug displayed. This command searches all the memory in Note Pad's heap for the text "carbon." Use single quotes and not double quotes. If MacsBug can find the text you're after, it will display memory showing it. The memory is dumped in raw hexadecimal format, with an ASCII translation on the right side. The address at the left side of the display shows where it was found. It might look something like this:

Searching for 'carbon' from 0738AA70 to 073BC96B
07396812 6361 7262 6F6E 6174 6520 6F66 2073 6F64 carbonate of sod

Listing 4 - Sample Find output

MacsBug returns the sixteen bytes of memory that start with the found data, so the address on the far left (in this example, 07396812) is exactly where your data was found. If that's in the middle of what you're searching for, you'll want to back up somewhat. Try subtracting a few hundred bytes from that address. Use the "log" command to start recording to disk, and then use the "dma" command (which stands for "display memory in ASCII format") to dump the memory you want, with a command like "dma 07396812-#300". Press Return a few times to dump more memory. When you have all you think you're going to get, type "log" to close the file.

The text won't be in perfect format, but with luck, you can use copy and paste to salvage much of it. Please note, however, that this is an iffy maneuver at best. Programs don't always store text data in contiguous chunks--if your word processor had hyphenated "bicarbonate" after the "r," it might have stored the two parts of the word in separate places, and searching for "carbon" wouldn't have worked. Also note that numerical data is almost never stored in ASCII format except in text files, so trying to find a number like "5.95" in a spreadsheet is almost certainly a lost cause. This won't necessarily cure problems you have--but if it's going to be a tremendous problem to reconstruct the data, it might be worth a try. Don't be jinxed just because certain MWJ staffers were doing exactly this in Silicon Valley in 1989 when the Loma Prieta earthquake struck and killed the system's power. Some crashes were just meant to be.

Cheap Auto Rebooting

This one's a bit more annoying, but it can be a measure of protection for those who run servers or other unattended systems. Now that the "RS" command is a little bit better in MacsBug 6.5.4a4, it will usually succeed in restarting a crashed system. "RB" works even more often, although it may require volumes other than the boot volume to go through the system's MountCheck routine, verifying that everything is fine even though the disk wasn't taken offline properly at shutdown. We'll use "RS" here, but you could use "RB" if "RS" causes problems.

Can MacsBug help if you have a server machine that needs to restart automatically? Yes, it can, in a non-subtle way. We've already seen macros, which are groups of MacsBug instructions executed as a single unit. For example, "StdLog" is a macro that dumps a whole bunch of system information to a file. Type "help StdLog" to see what all it does.

Although it's not widely known, MacsBug has a special macro called "EveryTime" that is executed, if it's defined, every time you enter MacsBug. The simple answer is to define an "EveryTime" macro that executes the command "RS", insuring that every actual crash forces the system to reboot. Note already that this won't help if the server hangs or locks up--only if it really crashes.

There's another catch, though--MacsBug won't execute the "EveryTime" macro the very first time it's entered. That's what the "FirstTime" macro is for, and it works similarly. The simple answer here is to define a "FirstTime" macro that says nothing but "G", the command to resume normal execution. If a FirstTime macro is defined, MacsBug will stop during the boot process and execute it, so defining this macro gives you a brief pause during startup while you enter and exit MacsBug. The next time you enter MacsBug, presumably because of a crash, it will execute the "EveryTime" macro--the "RS" command, restarting the system.

The combination means that every time after the first automatic entry, MacsBug will restart the system if you just enter it. Any crash, therefore, reboots the system. If the system then crashes on boot, you have a nasty loop going, but what do you want? MacsBug is free. To make this work, you'll have to define the "FirstTime" and "EveryTime" macro in a file, preferably one you drop in the "MacsBug Preferences" folder. Create a new file in ResEdit (or Resorcerer, which we use) and create a new resource in that file of type 'mxbm', or "MacsBug Macro." Both MacsBug itself and the "Debugger Prefs" file contain a template that will help you add a name and an expansion for the macro as shown here--the name is either "FirstTime" or "EveryTime", the expansion is "G" (for "FirstTime") or "RS" (for "EveryTime").

A Good Starter Set

These articles have barely scratched the surface of MacsBug functionality--but that's because (stop us if you've heard this) MacsBug is a programmer's tool. The stuff it does best, like stepping through code and gaining control at specific places in a program--just aren't useful items to non-programmers. That doesn't mean that MacsBug can't do you well; it just means that non-programmers won't understand much of what MacsBug does. You shouldn't feel intimidated by this--it's by design. Non-programmers don't understand some of the programming-specific text functions in BBEdit, either, but that doesn't mean it can't help you design killer Web sites.

There's lots more you can do. In MacsBug 6.5.4a4, try typing 'API StartupDispatch" to see selectors for the new routines added in Mac OS 8.1 to manage the startup process, inserted explicitly to help non-US systems load extensions in the right order on HFS Plus disks (MWJ 1998.02.02). This doesn't help very much, because no one outside Apple and a few developers (like Casady & Greene) have documentation for the routines yet, but you can find out what they're called. (Editor's note: These routines are now publicly defined by Apple.)

Or you can break into MacsBug in an application with lots of open windows and type the macro "WindList," which uses low-memory values to present a formatted dump of all the window records in that application. Try this in the Finder, pressing Return after each window to get the next, and you'll eventually run into the large, irregularly shaped window known as "Desktop," in case you wondered how that worked. Or type "thePort" to see the current QuickDraw graphics port disassembled for your pleasure.

MacsBug's ability to format data in memory along certain lines is quite powerful, although not quite as powerful as Quadrivio's General Edit, a program that can display any chunk of memory using a powerful formatting language that allows for conditional display, pop-up menus and more besides. These are valuable features for programmers, who can often disassemble complicated structures in memory using General Edit and source code from their programs to define the structures. Non-programmers usually couldn't care less about such things, since it typically takes someone with programming skills to diagnose problems in memory-based structures, repair them on-the-fly, and continue using the system. On the other hand, General Edit can apply the same deconstruction skills to files on disk, an area MacsBug doesn't touch. General Edit Lite handles many of the same tasks but without the advanced structure construction language or the ability to mess with individual chunks of memory. Still, General Edit Lite will be a good tool for your technical arsenal; programmers and very technical users will want to seriously consider the $200 General Edit for managing the content of binary files like never before.

Still, we think MacsBug can be quite useful for non-programmers in the situations, as this starter set of Nifty MacsBug Tricks shows. We urge you to be cautious with MacsBug--just as messing up one character in an HTML file can ruin a Web page, changing things on your system with MacsBug can cause more problems than you might realize, and that's why we've deliberately stayed away from the "sm" command and its variants, the ones that set memory values instead of just displaying them as "dm" does. We've kept to those commands that can make already-bad situations a little better, and those that can give you more information without actually changing anything. Making it useful is up to you.

© 2008, GCSF, Incorporated. All Rights Reserved.
This page last modified on Friday, December 12, 2008 3:42 PM

easyDNS provides DNS Hosting for MDJ and MWJ.