|
|
|
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. |