MacsBug for the Merely Geeky, Part Two
The first part of this article in TidBITS-449 looked at MacsBug, Apple’s free low-level debugger, explained how to install and invoke it, and how to use MacsBug to recover from application crashes. It also discussed looking up system error numbers with MacsBug, plus converting between decimal and hexadecimal and doing basic math.
This time, we’ll take a look at some MacsBug commands that reveal detailed information about your system and its applications. We’ll also explain a bit about how your Macintosh and applications use memory, as well as how to make problem logs using MacsBug. MacsBug still isn’t a friendly piece of software I’d recommend to all Macintosh users, but if you’ve come this far, going a little further won’t hurt.
By Your Command — Let’s take a look at some common (yet useful) MacsBug commands. These and other commands are case insensitive; it doesn’t matter if you capitalize them the way I’ve written them here. MacsBug also has a Help command that displays often-cryptic descriptions of these and other commands. Although you’ll see many of MacsBug’s capabilities have to do with obscure functions like traps, breakpoints, and disassembly, there are some useful gems to be found. Type Help Misc for a small sampling.
How – Displays the reason MacsBug was invoked. If you entered MacsBug deliberately, this command tells you the cause is an NMI (Non-Maskable Interrupt).
Stat – Displays the current date and time (along with how long since you last restarted the machine), the name of the current application, and some technical information about your system. Stat is handy for figuring out how long it’s been since you last restarted your machine – for instance, although it’s asleep much of the day, my PowerBook has been running for more than four months.
ProcInfo – Displays a summary of running applications (or processes), including faceless background programs. The status column indicates which program is in the foreground (this might be different from the currently executing program found under CurAppName), which applications are in the background, and which are background-only. You can also see the programs’ type and creator codes, along with how much memory they take and how much of that memory is free. These memory numbers are in hexadecimal: if you’re using a recent version of MacsBug, remember you can just click them and press Return to translate the numbers to decimal. This is a great way to find out how much memory is used by the Finder and background applications like File Sharing, Web Sharing, or Desktop PrintMonitor. Note that the total memory size listed here does not include any temporary memory in the system heap the application might be using; for instance, MacsBug might say Internet Explorer is using 5 MB of memory, while About This Computer under Mac OS 8.x could report a significantly higher number since it includes temporary memory with its totals.
File – Did you know that the Mac OS can open only 348 file forks – data and resource – at the same time? The File command displays a complete list of open file forks, sometimes including both the data fork and resource fork of the same file. In this list, you’ll see not only any documents or files you currently have open, but all your running applications, fonts, disk directories, extensions, plug-ins and shared libraries used by applications, and more. At the end of the list, you’ll see how many of the file forks are currently open: don’t be surprised if this number approaches 200. It’s not unusual for designers, production artists, programmers, and Web developers to open too many files inadvertently. Usually, quitting an application (or removing unused fonts) solves the problem. If you want to see which files a particular application has open, use the command File -P, followed by the process serial number of the program you’re curious about. Process serial numbers are four digits long, and listed in the first column of the ProcInfo command, above. To see all open files except for fonts, type File 0 (that’s a zero, not the letter O).
Vol – Displays information about all mounted disks. For the most part, you already know what disks are mounted on your desktop, but this command tells you a little more about them. First, it provides (in hexadecimal) separate totals for the number of files and folders on a drive, unlike the Finder’s Get Info command which just displays the total number of items. (It also tells you the allocation block size for a volume, but these numbers seem to be incorrect for HFS+ disks.)
StopAS – Shuts down connections to all AppleShare servers, whether you connected to them using AppleTalk or TCP/IP. (Earlier versions of MacsBug support the StopXPP command, which just closes AppleTalk connections.) For non-programmers, StopAS has two uses. First, you might want to shut down all AppleShare connections if a server is giving you trouble (like disk errors or slow response due to network congestion). Second, remember from the first part of this article that AppleShare servers give up on you if you spend more than a couple minutes inside MacsBug. There’s another downside: if this happens, when you exit MacsBug your applications will spend a couple more minutes in limbo wondering where these servers went. Using StopAS to shut down AppleShare connections eliminates delays when you come out of MacsBug.
DX – When programmers are debugging an application, they often insert commands called "user breaks" that deliberately trigger MacsBug. User breaks are helpful if a programmer needs to see what’s going on before a program crashes rather than after it has taken leave of the known universe. Programs released to the public don’t usually have user breaks, but sometimes they slip through: I have a script that commonly triggers a few in Eudora Pro, and I’ve seen plenty in pre-release and beta software. If you don’t have MacsBug installed and encounter a user break, the application is likely to crash with an error -10; with MacsBug installed, MacsBug will take over your system just like a system error, but will show the cause as a user break along with (sometimes) a message from the programmer. You can often just press Command-G to get out of a user break, but you should report the user break to the developer as a bug. However, if you hit an annoying one and you’re trying to get work done, you can use the DX command to tell MacsBug to ignore user breaks: DX OFF turns user breaks off, DX ON turns user breaks on, and DX NOW tells you whether user breaks are enabled or disabled without changing their status. If you turn user breaks off, MacsBug turns them back on again when you restart your machine.
Thanks Heaps — Each application running on your Mac stores windows, dialogs, documents, and other data in an area of RAM called its application heap. The size of a heap varies with the amount of memory allocated to an application. The system also has a heap, and it’s the only one the Mac OS can resize on the fly. To change the size of an application heap, you must quit the program, change its memory settings in its Get Info window, then re-launch the program. This is one of the reasons proponents of other operating systems say the Mac OS has a weak memory model.
Heaps are divided into blocks, which can either be free (unused), relocatable (in use, but movable), or locked (in use and unmovable). Blocks in use can also be marked as purgeable, meaning that the application would prefer the data stay in RAM, but it can be released (purged) if the program needs more free memory. Each block of memory begins with a header containing some information about the memory block.
An application heap is a little like a disk in that it can become fragmented. As a program uses and releases memory (say, opening and closing documents), both free and occupied blocks of memory can become scattered throughout the heap. If the blocks are relocatable, the application re-organizes them to create larger areas of free space – just like optimizing a hard drive. If the blocks are locked, however, they can’t be moved and the application may not be able to handle requests for large blocks of memory (say, to open a big document), even though there might be enough total free memory for the request.
Given this, you might wonder why programs ever use locked blocks. The reasons vary, but a good example is playing a movie. If the memory block containing a movie could be moved at any instant, the application would constantly have to check whether the memory had moved, which would destroy performance. By being able to guarantee the block won’t move, the program can concentrate on playing the movie, then (in theory) give back the memory when its done. Some applications use more locked memory than others, but all applications use some.
Heaps can also become corrupted, usually when a program puts more data into a block than it was intended to hold. When this happens, it usually overwrites the header of the next block, and the Mac’s Memory Manager loses track of that next block. The consequences can range from unnoticeable to disastrous, depending on the nature of that next block of memory.
If you’d like a program that graphically displays areas of an application’s heap (and can peer into heap blocks), check out Joshua Golub’s ZoneRanger, a 517K download from Metrowerks’s Web site. It’s a little unstable under recent versions of the Mac OS, but it’s useful and educational.
MacsBug can tell you heaps about your heaps.
HT – The HT (heap total) command displays information about the current application’s heap, including the amounts of free, relocatable, locked, and purgeable memory. HT provides results in hexadecimal and decimal numbers, expressed in bytes: you can use this command to see a bit of what’s happening behind the scenes. If a program reports it’s running low on memory but the HT command shows a large amount of free RAM is available, then the heap is probably seriously fragmented. You can try quitting and relaunching the application. If the problem persists, however, allocating more memory to the program may not solve the problem, since large areas of memory can be fragmented just as easily as smaller ones. (Of course, if a program complains it doesn’t have enough memory and HT shows there truly isn’t much memory available, then increasing the application’s memory allocation should help.)
HZ and HX – The heap total command, HT, works only on the current heap. How do you get information on a heap belonging to a different application? First, you need information about the other heaps, available via the HZ (heap zones) command. HZ lists all the heaps, complete with the names of the applications to which they belong. Each item on HZ’s listing begins with a decimal number, starting with #1. You can use these numbers with the HX (heap exchange) command to switch to a particular heap. So, if HZ indicated Nisus Writer’s heap was #9 on my machine, I could type HX #9 to switch to Nisus Writer’s heap regardless of which application was running when MacsBug was invoked. Once I’d done that, the HT command would show me information about Nisus Writer’s heap.
HC – The HC (heap check) command tells MacsBug to check if the current application heap is corrupted; you can use HC ALL to check all heaps at once. You might try this if an application is behaving oddly but not crashing. If the HC command reports a heap is corrupted, things may get worse quickly: save all your work and quit the application. Note that this command can be fooled into thinking a heap is corrupted if MacsBug is invoked while an application is shuffling blocks around using the Memory Manager. There are ways you can tell MacsBug to keep running until a safe moment, but it’s usually simpler to leave MacsBug using G (or Command-G), wait a second, then re-enter MacsBug to see if the problem persists. If you’re curious, look up the WNE and WNEPPC (only available in recent versions of MacsBug) commands in MacsBug’s help.
Logging Problems — Because MacsBug is so good at uncovering information about your current application and the state of your Macintosh, it’s useful for folks who are testing or evaluating software, as well as for software programmers. The only difficulty is determining what information is relevant when you’re reporting a bug.
Fortunately, the folks who make MacsBug have made this easy for you. The StdLog command, as the name implies, creates a text file with a standardized log of information developers commonly need when they’re investigating a bug. These logs are pretty big (usually about 20K), and contain the results of several MacsBug commands, including many discussed here. When you use the StdLog command, the log appears as a text file named StdLog on the desktop. If you use the StdLog command again, the information will be appended to any existing file named StdLog, rather than overwriting it.
Unless you’re already in contact with the program’s developer, I don’t recommend sending a standard log via email as a bug report. Instead, describe the bug succinctly, and indicate you’ve made a MacsBug log of the problem, which you can send they like. Hang on to the file. Some developers will disagree with me, but, having handled my share of bug reports received via email, large reports with attachments are more awkward than concise notes. Frankly, if a program is in public testing, there should be few new bugs turning up. It’s not particularly useful for a developer to receive dozens of log files about a problem that’s already known and possibly already fixed.
Another Break Point — In the next part of this article, we’ll take a quick look at using MacsBug to restart machines automatically in the event of a crash. If you’d like more information about MacsBug, check out Apple’s MacsBug Reference and Debugging Guide, available in Acrobat PDF format. Although it hasn’t been updated since MacsBug 6.2 in 1991, this guide still offers detailed information on the inner workings of Macintosh memory management, plus traps, disassembly, and much more.
In addition, the weekly journal MWJ published a lengthy two-part article earlier this year called MacsBug for Non-Programmers, which discusses several MacsBug features not covered here, including analyzing heaps and both displaying and searching memory. Both parts are reprinted on Ted Landau’s MacFixIt site. If you can’t get enough insightful Macintosh news, sign up for a free, no-obligation, three-week trial subscription to MWJ in time for their Mac OS 8.5 coverage, or download some free sample issues.