TweetFollow Us on Twitter

MacsBug Revisited

Volume Number: 15 (1999)
Issue Number: 6
Column Tag: Tools Of The Trade

MacsBug Revisited

by Daniel Jalkut

This is not your father's low-level debugger


MacsBug is an extremely powerful, low-level debugger which Apple maintains and distributes for free to developers of Mac OS software. From its humble beginnings as the Motorola Advanced Computer Systems Debugger in 1981, it has evolved into the debugger that many developers both inside and outside of Apple depend upon to get their jobs done.

The aim of this article is not so much to introduce MacsBug as it is to reintroduce it. Enough basic introductions to MacsBug have been written that I don't believe a repetition is necessary. If you are interested in a detailed description of MacsBug's basic features, I suggest you consult one of the publications mentioned at the end of this article. I suspect that most of you have heard of MacsBug, and a majority of you has probably used it to varying extents. I hope to provide something that each of you can use to further your use of MacsBug in the battle against buggy code.

In recent years, MacsBug has received less attention from Mac OS technical publications than it did in the past. Many developers have switched to using source-level debuggers like the one included with Metrowerks CodeWarrior. Those debuggers, while very convenient for the majority of bug diagnoses, have a limit to their usefulness. MacsBug continues to prosper because of the elegance with which it allows developers to overcome limitations of higher level debuggers. This article is divided into three sections, each of which discusses a different aspect of this elegance.

The first section is a high level discussion of the thinking that goes on when diagnosing a bug, and a description of some basic approaches you can take to work out the diagnosis with MacsBug. The second section extols the virtues of MacsBug's extensibility, a feature that should appeal to those of you with highly specialized or unpredictable debugging needs. Finally, the third section divulges some of the exciting features that MacsBug has gained in the past couple of years, which should convince the biggest MacsBug skeptic that something here deserves a second look.

Before you experiment with any of the functionality described in this article, I highly recommend downloading the most recent version of MacsBug from Apple's MacsBug web site: <>.

Part One: The Debugging Mindset

I don't know anybody who has mastered MacsBug. Like Herman Hesse's Siddharta and his pursuit of nirvana, the mastery of MacsBug is a lifelong journey for which there is no apparent end. This humbling reality, while disheartening, must not prevent you from using what you do know to battle any bugs you encounter along the way! Like chess, the basic tools can be easily taught, but the secrets of winning are learned only by developing a mindset which allows you to apply simple techniques in new and exciting combinations. In this section, I will describe a basic approach to debugging in MacsBug, which you can expand upon as you develop your own debugging style.

MacsBug is typically encountered by one of two mechanisms: intentional or unintentional CPU exceptions. An exception is just what it sounds like - a deviation from the normal course of operations. Intentional exceptions occur when you, the programmer, premeditate an event that causes MacsBug to interrupt the execution of code and display the state of the computer on the screen. Unintentional exceptions occur when somebody's code crashes. The mentality for dealing with either case is different.

When you break into MacsBug intentionally, either by a breakpoint ("tvb", "atb", "br", "brp") or a programmed exception in your code (Debugger or DebugStr), you typically want to examine the state of things at a particular point in your code's execution. Typical reactions to an intentional MacsBug entry are to check that the parameters of a function look correct (e.g. "dm r3"), that the heap is not corrupt ("hc"), or to step through ("s", "t") code one instruction at a time and ensure that your code does what you think it should. MacsBug is perfectly suited to debugging in these circumstances, but since this type of debugging is especially well suited to a source-level debugger, I will focus only on unintentional interruptions (crashes).

When MacsBug is encountered as the result of a crash, you don't have the same luxury of understanding the circumstances as you do in an intentional interruption. Three very important questions to ask are: "What caused the crash?", "Where am I?", and finally "How did I get here?" The answers to these questions will greatly increase the odds of pinpointing the problem. Let's discuss some basic strategies for answering each question in turn.

What Caused the Crash?

MacsBug interrupts the execution of code when that code violates the rules of the CPU. If you are lucky, MacsBug's explanation of the crash will provide some insight into the problem. MacsBug displays the explanation immediately after it appears, and the explanation can be repeated by issuing the "how" command (a caveat is that MacsBug forgets this information as soon as you step or trace). Usually, the information provided is broadly useful, but doesn't specifically pin down the cause of the crash. Among the most common causes of crashes are memory exceptions and illegal instructions.

Memory exceptions occur when a piece of code tries to read or write from memory that either doesn't exist (is not part of the address space) or which exists but is off limits to the crashing code. When this is the cause of a crash, the basic approach is to look at the instruction that is causing the crash, and try to figure out where the bad address came from. If you're lucky, the address was the result of the last subroutine called, and you know the culprit immediately. If you're not so lucky, finding the origin of the address might involve tracing back through hundreds of lines of MacsBug disassembly, across several levels of subroutine calls.

Illegal instructions are sequences of bits that make no sense to the CPU. The CPU depends on receiving a stream of instructions that corresponds exactly to actions it knows how to perform. For instance, the hex value 0x38600000 means to the PowerPC processor "put the value zero in register r3". When the PowerPC processor receives a hex value like 0x11111111, it means nothing to the CPU so it causes an illegal instruction exception. When you reach MacsBug because of an illegal instruction, you are usually facing a bug where the program counter is pointing to data instead of code. There is a small chance that your compiled code contains illegal instructions, but this is unlikely unless there is a bug in the compiler, or you compiled for a specific CPU (Motorola 68030 for instance) and tried to run on a different CPU (Motorola 68000 for instance). Since the overwhelming majority of times you hit an illegal instruction will be because you are executing data instead of code, the solution to this problem requires answering the questions "Where am I?" and "How did I get here?".

Where Am I?

You know why the computer crashed, but this information is useless if you don't know the culprit code that caused it. There are three types of crashing code in this world: your code, other people's code, and data.

If you are building with symbols and traceback tables enabled, as you should be for pre-release builds, MacsBug will make it immediately clear whether you are executing your own code or somebody else's. If MacsBug prefaces the disassembly in the program counter display with a symbol, and you recognize the symbol as one of your routine names - congratulations your code crashed!

It Came from Beyond...

If there are no symbols, and the code doesn't scream out to you what it does (immediate recognition of assembly code's purpose is an uncommon, but real skill), you are going to have to dig deeper to find out exactly whose code it is. An immensely useful MacsBug command is the "wh" (short for "where") command, which identifies as best it can the characteristics of a location in memory. Commonly, this command is issued without a parameter, which causes it to give information about the current location of the program counter. The output of the "wh" command ranges from "very useful" to "not so useful, but I'll take it" to "pretty darn useless."

In the "very useful" category, when the code you are executing is part of a PowerPC code fragment, the name of the fragment will be displayed along with the offset into the fragment of the particular line of code. The name of a PowerPC code fragment can be either an application name, a library name, or the logical name given to any piece of PowerPC code that is stored in a fragment. Usually, the name will implicate your application, another application, or a piece of System Software code.

If the code is 68K code or is not part of a CFM library, the result of the command may be simply information about the Mac OS memory manager block in which the code resides. This is less immediately useful than a library name, but you can sometimes figure out whose code it is by examining the memory block for clues. In particular, if the memory block is being tracked by the Resource Manager, then additional information about the resource, including the file it came from, are included in the output of the command. A good second stab is to take a look at the first several bytes of the memory block, which sometimes contain symbols or character codes (e.g. 'PLUG', or '"Apple Menu Options") which will sometimes bring you closer to the identity of the code's owner.

In worst case scenarios, the code you crashed in is not even code that the Mac OS memory manager keeps track of, and all MacsBug can muster is that the address is "in RAM but not in a known heap." Aside from displaying memory around the program counter and hoping for a lucky find, you are pretty much lost. This doesn't mean you aren't going to find the bug, it just means you have to do so without the benefit of knowing what the crashing code is.

Executing Data

Since data and memory coexist in the same address space of the Macintosh, and since the Mac OS provides only limited memory protection (for file-mapped PowerPC libraries), it is entirely possible that the CPU will be handed a chunk of data and be asked to execute it as code. If you are at all familiar with the assembly language for the CPU you are debugging, it will usually be immediately clear whether you are in data or code memory. When you look at the code at and around the program counter ("ip"), does it look like assembly language or does it look like MacsBug trying to translate monkey talk to a rhinoceros? Common giveaways are if the disassembly contains a lot of "ORI.B" instructions (68K), or a lot of "dc.l"" instructions (PowerPC). This is because the hex representations of these instructions are 0x00000000, and data memory usually contains a lot of zeroed-out memory.

If the memory looks like data, you are one step further to solving your bug. Usually the data contains patterns or text which are characteristic of the code that owns it. Find the beginning of the memory block with the "wh" command, and display memory from the beginning of the block until you find something that looks incriminating. Whether you can cinch the owner or not, it is time to move on to the next stage.

How Did I Get Here?

If you have been lucky, you now know the fundamental cause of the crash, and you know whose code it is. That knowledge is mostly useful for providing clues to answer the ultimate question: "how did my cute fuzzy bunny code get coerced off its path into the cruel, crashing world?" Unless the nature of the crash or the location of the code was telling enough to reveal an obvious solution, you must now attempt to turn back the clock and study the sequence of events that led up to the crash. Fortunately, a time machine is built into most calling conventions in the form of stack based link addresses.

When a subroutine is called, the caller needs to communicate to the subroutine how it will return control to the caller. It is abundantly common for this information to be passed along on the stack. As each subroutine in turn calls its own subroutines, a bread crumb trail is left that snakes all the way back up the stack to the original caller. Examining this trail is referred to as performing a "stack crawl." If you were really hard up, you could display memory from the stack pointer for several hundred bytes, reason out the math implied by the values in the various positions, and determine for yourself which parts of the stack refer to return addresses. Fortunately, MacsBug does a fairly good job of doing this with its 'sc' command.

The "sc" command was originally only able to examine the stack for 68K calling conventions, but today it is capable of looking for both 68K and PowerPC subroutine calls, and listing them both in the same stack crawl listing. In the output, each line represents the location of an instruction that caused a subroutine to be called. The last entry displayed is the last subroutine call MacsBug could decipher from the stack. If you look at the list from bottom to top, you are examining the subroutine history, from most recent to oldest, that led to this point. Generally, you are looking for a piece of code that looks like it is yours. If you find it, disassemble the code at that address ("ip <address>") to see if you can figure out exactly which of your code it is. Once you determine this, your strategy shifts from unintentional to intentional debugging - move on to a source level debugger if you so desire. You can now set break points at the crashing subroutine call and reproduce the crash on your terms.

There's No Stack Crawl!

Sometimes, as you should expect by now, things do not work out quite so peachy. The stack and link registers are sometimes in a state such that MacsBug is of no help in examining the stack crawl. Situations such as these call for desperate actions. Even if MacsBug refuses to produce a useful stack crawl, you can search for clues by looking at the link register contents yourself. Remember the "wh" command? Try "wh lr" to get information about the address in the link register, and "ipp lr" to disassemble the code surrounding the address (and hopefully the code that got you where you are).

MacsBug also provides a second stack crawl command, "sc7", for situations where the first does not pan out. Its output is identical in structure to that of "sc", but it is much less finicky about what constitutes a "return address" on the stack. The "sc" command actually iterates backwards up the stack, examining the locations which algorithmically (based on the well-defined calling conventions) should point to code which called a subroutine in the call chain. The "sc7" command, on the other hand, will examine every address on the stack, and as long as the code an address points to appears to immediately follow an A-trap or subroutine call, it will list the address as a "possible return address." Thus, the results of the "sc7" command need to be taken with great skepticism, but as I said, this is a command for desperate situations.

I Mean There's No Stack Crawl!

If the stack crawl is not panning out in any way, shape, or form, there is another technique that may be of aid. For whatever reason, the code you crashed in is just not conducive to the usual stack crawl analysis. If the crash you are debugging, however, can be temporarily avoided, then it may bode well to circumvent the crash, trace until the code you are executing is returned from, and see if the stack at this point is in better shape. If not, and if your crash-workaround lasts, just keep tracing until you do get some place interesting!

Crashing code can be avoided either by jumping past it (directly setting the PC register to a later address, e.g. "PC = PC + #12"), or by manipulating the registers such that a crash does not occur (put a valid address like MacsBug's built-in "playmem" in the register that is causing a memory exception). As you become more comfortable with direct manipulation in MacsBug, you will find that your debugging options increase immensely. Be aware, though, that you can make a bad situation worse by trying to "fix" things yourself in MacsBug. Hopefully, if you are reading this article, you understand that the risks of data loss and corruption are higher than average on the machine of a programmer. I am usually more interested in getting the bug fixed than playing it safe with my computer, but then again, I do make regular backups!

Part Two: Custom MacsBug Features

MacsBug has always been evolving. Three important features of MacsBug - the ability to define macros, the ability to define templates, and the ability write dcmds - have enabled MacsBug to evolve, meeting the needs of programmers over the years with relatively few changes to the core of the program. I shall now give an overview of these features, because MacsBug simply can not be appreciated without understanding these gems.


A MacsBug macro, like a macro in other programs, is a word that is translated when it is evaluated to mean something else. A simple example is the "windlist" macro. You might type this and assume it is a command that is built into MacsBug, but it is in fact a macro! Macros are defined by resources of type 'mxbm', several of which are included in MacsBug's own resource fork. The list of macros that MacsBug knows about can be displayed by typing "mcd" into MacsBug. If you look at the resulting list, you will see the meaning of the "windlist" macro is defined as "dm @WindowList WindowRecord", where "dm" is a built-in MacsBug command, "WindowList" is another macro defined as the number 0x09D6, and "WindowRecord" is a template. This simple macro, then, means "display the memory pointed to by an address at location 0x09D6, and format the contents of the memory with the WindowRecord template."


Templates, packaged in resources of type 'mxwt', contain information about how to format memory that is displayed by MacsBug. Using the MacsBug "dm" command (display memory), a template is invoked by typing its name as a second parameter, after the memory address you wish to display from. Without a template, MacsBug uses a default output structure, which consists of lines of hex values with an ASCII translation to the right side. Often, a more readable format is preferable. Specifically, you would prefer a format as similar as possible to the structure definition in your code. In the case of WindowRecord, a simple memory display produces the following output:

 dm @windowlist
 Displaying memory from @09D6
 005D45D0 0000 0071 DE40 C000 0071 DF04 0000 8000 ***q&THORN;@&iquest;**q&thorn;***&Auml;*
 005D45E0 0000 0000 0094 0068 007D 5DD8 0000 2DBC *****&icirc;*h*}]&yuml;**-&ordm;
 005D45F0 0071 DE24 0000 0000 0000 FFFF FFFF FFFF *q&THORN;$******ùùùùùù
 005D4600 0064 005C 0001 0001 0008 0058 73B0 005D *d*\*******XsÉ*]
 005D4610 431C 0000 0001 0000 0001 0009 0000 0000 C***************
 005D4620 0000 00FF 0000 0000 0000 0000 0000 0000 ***ù************
 005D4630 0000 0000 0000 0000 0000 0000 FFF3 0101 ************ù&Ucirc;**
 005D4640 0100 0071 DEE4 0071 DE38 0071 DE78 0000 ***q&THORN;î*q&THORN;8*q&THORN;x**
 005D4650 2DC4 0000 0000 0071 DE5C 0041 0000 0000 -ü*****q&THORN;\*A****

While displaying the same memory with the WindowRecord template produces:

 dm @windowlist WindowRecord
 Displaying WindowRecord at 005D45D0
 005D45E0 portRect			#0 #0 #148 #104 (w #104, h #148) 
 005D45E8 visRgn				007D5DD8 -> #0 #0 #148 #104 [non-rect] 
 005D45EC clipRgn			00002DBC -> [wide-open region] 
 005D463C windowKind		FFF3 
 005D463E visible			true 
 005D463F hilited			true 
 005D4640 goAwayFlag		true 
 005D4641 spareFlag		false 
 005D4642 strucRgn			0071DEE4 -> #13 #87 #181 #193 [non-rect] 
 005D4646 contRgn			0071DE38 -> #32 #188 #180 #192 [non-rect] 
 005D464A updateRgn		0071DE78 -> [empty] 
 005D464E windowDefProc	00002DC4 -> 008D9C00 -> 
 005D4652 dataHandle		NIL 
 005D4656 titleHandle		0071DE5C -> 008DA0E0 -> "Calculator" 
 005D465A titleWidth		0041 
 005D465C controlList		NIL 
 005D4660 nextWindow		NIL
 005D4664 windowPic		NIL 
 005D4668 refCon				00000000

Instead of 136 bytes of hex spewed onto the screen, you get a fairly nice looking description of the window in the form of a WindowRecord structure. An added bonus of displaying memory via a template: a template definition can contain certain types which MacsBug knows are referred to by pointers in the memory being displayed. When MacsBug displays these elements, it follows the addresses to the data of interest, and displays that in a readable format. Great examples in the listing above are the "visRgn" and "titleHandle" fields.

Debugger Commands

"Debugger commands", or dcmds, are independent pieces of code which MacsBug allows you to execute from the command line while you are debugging. These commands, packaged in 'dcmd' resources, are the most significant contributors to MacsBug's extensibility. There are limitations to the types of code that dcmds can execute, and output is restricted to text displayed via MacsBug's text screen, but for most of your specialized debugging needs, the facilities of the dcmd architecture will be perfect. Like macros and templates, much of the behavior taken as "built-in" to MacsBug is actually implemented in the various dcmds that come pre-installed with MacsBug. To get a list of the dcmds available to you from MacsBug, type the "dcmd" command itself. The result is a list of the commands at your disposal. To get help on any of them, type "help [name of dcmd]" (or just "? [name of dcmd]"), which will cause the dcmd itself to explain its own functionality.

Roll Your Own Debugger

Obviously the power of extensibility is most appreciated when you have occasion to require a custom addition to the built-in functionality of MacsBug. Some MacsBug enhancements can be found in the public domain, or in friends' private collections. These enhancements are easily installed by dragging the resource files in which they were delivered into a folder called "MacsBug Preferences" inside your Preferences folder. MacsBug will retrieve the resources from all such resource files when it initializes itself early in the boot process. You could also use ResEdit to copy and paste the resources into MacsBug itself, but by leaving them outside of MacsBug, you can easily keep the enhancements when you update to future releases of MacsBug.

If you can't find the enhancements you need on the Internet or from your geeky friends, you will have to resort to writing your own. Fortunately, writing templates and macros is very simple, and programming dcmds takes only a bit more effort. To get started on templates and macros, open up MacsBug with ResEdit and look at some of the built in examples. You can copy the 'TMPL' resources from MacsBug to your own resource file, which will allow you to edit macros and templates with ResEdit's template (not to be confused with MacsBug templates) editor. A sample dcmd project is included in both CodeWarrior and MPW format in the MacsBug release archive. Once you've learned to concoct your own MacsBug enhancements, you will be free to dream up completely new ways of solving your debugging problems.

Part Three: MacsBug Enters the Millennium

Now it is 1999, and the MacsBug available on Apple's web site is much different than the MacsBug first rolled off the line in 1981. Here are some of the features of MacsBug that might surprise you if you haven't been paying attention to the most recent MacsBug releases.

Mouse Support

MacsBug supports simple operations involving the Mouse. Yes, break into MacsBug and move the mouse around. It's not a bug - click on some items in MacsBug's display to get a feel for the effects. Mouse support is handy when you don't want to retype an address that is already displayed on the screen into a MacsBug command expression. Another popular use is for changing the height of the PC section of MacsBug's display - just click and drag!

CFM Symbol Execution

How many times have you wanted to execute a particular Mac OS API call from within MacsBug, but you didn't have a dcmd to do it for you? If you are an especially adept MacsBug user, you might have done this in the past by extreme MacsBug direct manipulation. You would write down or save in macros the contents of the registers, switch the PC to a free spot in memory, type out the hexadecimal code that prepares the stack and calls an A-Trap, and trace over the A-Trap before finally restoring the state of registers, the PC, and the stack to their original values.

Thankfully, MacsBug now possesses an amazing functionality that obviates the need for this kind of hacking. You can ask MacsBug to execute any routine that is exported by a CFM library, directly from the MacsBug command line. Since almost every Mac OS API routine is exported through some library (even if it's only glue code to get to the 68K implementation), you have access to almost any Mac OS API call that could assist in debugging your code! To execute an exported routine in MacsBug, simply preface the routine name with the © symbol (option-G), put the parameter list in parentheses as you would in a C function call, and press return. The return value of the function is the MacsBug expression value returned by the command. For example, if you type the MacsBug command:

 ©MoveWindow(@WindowList, #100, #100, 0)

The window that is front-most in the current application is moved to location (100, 100) on the screen, and MacsBug returns the following output:

 ©MoveWindow(@09D6, #100, #200, 0) = $000000FF  #255  #255  '***ù'

The value of the expression in this case should be ignored, because MoveWindow does not have a defined return value. Another simple example:


Causes MacsBug to return the following output:

 ©HMGetBalloons() = $00000000  #0  #0  '****'

Which tells me that Balloon Help is currently inactive. Clearly, there is enormous potential for this feature, and you will only know how handy it is when you remember that it's there in the midst of a really tough bug.

The feature does have some drawbacks, of course. First, you must phrase all of the parameters to the routine as explicit values. MacsBug doesn't know how to translate the text "true" into a valid numeric value for the function you are calling. Second, if any of parameters are pointers that receive an output value (VAR parameters), you are responsible for passing an address to a legitimate memory location. I am in the habit of using playmem for such things. For example:

 ©GetIndString(playmem, #128, 1)

Which gets the first string from 'STR#' resource 128 and copies the string to the "play" memory reserved by MacsBug. You can now display the contents of the string by typing "dm playmem". Last, and most importantly, MacsBug will not police the safety of the CFM call you are making! Calling routines at certain times and with certain parameters may spell death for your debugging session. Among the factors to consider are: the interrupt level, the reentrancy of code that is currently being executed, and the state of the file system if the routine you're calling will access files. In general, this feature falls into the "desperate actions" category, but as you come to depend on it, you may enjoy being desperate!

PowerPC Watch Points

A number of MacsBug's features evolved during the years when Macintosh computers ran solely on Motorola's 680x0 series of CPU. Since the introduction of the PowerPC based Macintoshes, MacsBug has continued to evolve, albeit sometimes slowly, implementing functionality for PowerPC that matches what we grew accustomed to on 680x0 computers.

One very useful feature for 680x0 code is called "step spying", and it can still be activated by using the "ss" command. Basically, what step spying does is to execute instructions one at a time, checking at each step whether a particular range of memory was written to. This is very useful when you have found a bug that is caused by the wrong data being written to a location in memory, and you want to find the culprit. You set a step spy on the address, wait for the computer to sluggishly execute instructions one by one, and hopefully when you break into MacsBug again, you are staring at the code that writes the bad value to that address.

Since step spying is implemented by stepping, instruction by instruction, through 680x0 code, it is completely useless when the offending code is in PowerPC format. MacsBug users who have needed step spy style functionality for PowerPC code have been essentially out of luck for quite some time. Steadily, however, a new functionality in MacsBug called "watch points" has been developing. With release 6.5.4a6 of MacsBug, this functionality has become remarkably more functional and substantially less likely to crash your machine.

To set a watch point in MacsBug, type "wp" followed by one or two addresses. If you specify one address, MacsBug will watch the 4 bytes at that location. If you specify two addresses, the range of memory bounded by the two addresses will be watched. Watch points are implemented by using the memory protection feature of the PowerPC processor. When you specify a watch point, the memory pages that contain the given range are write protected. When some piece of code tries to write to one of the protected pages, MacsBug's exception handler is called, which triggers a break into MacsBug if the attempted write was in the desired range. Watch points stay in effect until you clear them by using the "wpc" command.

The watch points functionality is in its infancy. There are a number of limitations that are described in the release notes:

  • To use the watch points functionality, you must install the Emulator Update file from MacsBug's distribution archive into your System Folder.
  • The emulator update only works on Power Mac 9500 and newer machines.
  • No more than one watch point can be set at a time.
  • When a watch point is hit, you may not safely trace or step until clearing the watch point.
  • Watch points can not be set on memory locations on the stack, memory that will be addressed with an atomic instruction ("lwarx" or "stwcx"), or the memory location zero.

The limitations are significant, but those of you who have been waiting patiently for a successor to step spying will be able to look past them and appreciate the mere existence of this feature. I can see your head nodding along right now, "I don't care if it's buggy, I need that feature!" Well, there you have it.


MacsBug is a very powerful debugger. If you didn't believe so before reading this article, I hope you will now agree, and I hope you will find occasion to make use of its power in your own debugging pursuits. For those of you who didn't need to be convinced, I hope that the new features will refocus your attention on the intrepid debugger that, to this day, is critical to Mac OS development everywhere. Remember, the most powerful way to grow the functionality and evolve this debugger into the next century is by writing and distributing your own dcmds, macros, and templates to the Mac OS developer community. MacsBug's evolution is not controlled by one person, one company, or one country - it's up to you to continue improvising and revolutionizing the functionality of a very simple, very complicated development tool.

Suggested Reading

The following are good references for those of you who need a more detailed review of MacsBug's functionality.

Apple Computer, MacsBug Reference and Debugging Guide, available online at

Othmer, Konstantin and Jim Straus. Debugging Macintosh software with MacsBug, Addison Wesley Publishing Company, Inc.


Thanks to Dave Lyons and Jim Murphy for reviewing this article, and for being the primary caretakers of MacsBug for the past several years.

Daniel Jalkut is a software engineer in the Mac OS System Software group at Apple Computer. In his spare time, Daniel works on solo projects under the moniker Red Sweater Software, and enjoys being a pedestrian in the beautiful city of San Francisco. You can contact him, or view his home page at


Community Search:
MacTech Search:

Software Updates via MacUpdate

jAlbum 19.2 - Create custom photo galler...
With jAlbum, you can create gorgeous custom photo galleries for the Web without writing a line of code! Beginner-friendly, with pro results - Simply drag and drop photos into groups, choose a design... Read more
BlueStacks 4.140.13 - Run Android applic...
BlueStacks App Player lets you run your Android apps fast and fullscreen on your Mac. Feature comparison chart Version 4.140.13: Highlights/Bug Fixes: Feel free to use BlueStacks as your go to... Read more
Adobe Premiere Pro CC 2020 14.0.1 - Digi...
Premiere Pro CC 2020 is available as part of Adobe Creative Cloud for as little as $52.99/month. The price on display is a price for annual by-monthly plan for Adobe Premiere Pro only Adobe Premiere... Read more
VirtualBox 6.1.2 - x86 virtualization so...
VirtualBox is a family of powerful x86 virtualization products for enterprise as well as home use. Not only is VirtualBox an extremely feature rich, high performance product for enterprise customers... Read more
RoboForm 8.6.8 - Password manager; syncs...
RoboForm is a password manager that offers one-click login, mobile syncing, easy form filling, and reliable security. Password Manager. RoboForm remembers your passwords so you don't have to! Just... Read more
Postbox 7.0.11 - Powerful and flexible e...
Postbox is a new email application that helps you organize your work life and get stuff done. It has all the elegance and simplicity of Apple Mail, but with more power and flexibility to manage even... Read more
calibre 4.9.0 - Complete e-book library...
Calibre is a complete e-book library manager. Organize your collection, convert your books to multiple formats, and sync with all of your devices. Let Calibre be your multi-tasking digital librarian... Read more
Notability 4.2 - Note-taking and annotat...
Notability is a powerful note-taker to annotate documents, sketch ideas, record lectures, take notes and more. It combines, typing, handwriting, audio recording, and photos so you can create notes... Read more
FoldersSynchronizer 5.0.1 - Synchronize...
FoldersSynchronizer is a popular and useful utility that synchronizes and backs-up files, folders, disks and boot disks. On each session you can apply special options like Timers, Multiple Folders,... Read more
Sketch 62 - Design app for UX/UI for iOS...
Sketch is an innovative and fresh look at vector drawing. Its intentionally minimalist design is based upon a drawing space of unlimited size and layers, free of palettes, panels, menus, windows, and... Read more

Latest Forum Discussions

See All

The Alliance update to Out There: Omega...
Out There is an old go-to recommendation for a lot of mobile stalwarts, but I could never really get into it. This sci-fi survival game that blended elements of interactive fiction and roguelike mechanics just felt a little off-balance and a little... | Read more »
Animal Fury Destination is an action-adv...
Animal Fury Destination is an action-adventure game from independent, Colombian developer Ignicion Games. It's a 3D action game where you'll play as various different characters as you embark on a quest to stop an evil crow sorcerer. [Read more] | Read more »
Shadowgun War Games Closed Beta Impressi...
Shadowgun: War Games is an upcoming free-to-play multiplayer shooter that’s essentially just an Overwatch knock-off. There are hero characters with special abilities, and you compete in 5-v-5 game modes where the goal is to use superior team... | Read more »
Slingsters is a physics-based puzzler fo...
Slingsters is a physics-based puzzle game where the aim is to collect various different monsters by flinging them from one side of a level to the other and into a box. It's also the first game from Nappy Cat and is available now for iOS and... | Read more »
Spiritwish's latest update sees the...
A sizeable update has hit Nexon's MMORPG Spiritwish today. It brings a new game mode, characters and there will also be a special event to celebrate the update with a firework display. [Read more] | Read more »
Maze Machina, a turn-based puzzler from...
The latest game from Arnold Rauers also known as Tiny Touch Tales is now available. You may be familiar with one of his many excellent titles such as Card Crawl, Enyo and Card Thief. His latest endeavour is called Maze Machina and you can grab it... | Read more »
Mario Kart Tour's Ice Tour races to...
Can you believe Mario Kart Tour is already on its 9th tour? The game only launched back in September, and since then it's become increasingly tricky to keep on top of the amount of new content Nintendo is pumping out. [Read more] | Read more »
Apple Arcade: Ranked - Top 50 [Updated 1...
In case you missed it, I am on a quest to rank every Apple Arcade game there is. [Read more] | Read more »
Marvel Future Fight's latest update...
Marvel Future Fight's latest update has added an all-new team of heroes to recruit and do battle with. The 'Warriors of the Sky' include Blue Dragon, War Tiger, Sun Bird, and Shadow Shell. As is the norm, each character comes with their own unique... | Read more »
Klee: Spacetime Cleaners is a fast-paced...
Klee: Spacetime Cleaners is a fast-paced auto-shooter that sports a cute retro aesthetic thathad racked up an impressive 100,000 pre-registers prior to its release. It's available now for both iOS and Android. [Read more] | Read more »

Price Scanner via

Just in! Apple iMacs on sale for $100-$150 of...
B&H Photo has new 2019 21″ and 27″ 5K iMacs on stock today and on sale for up to $150 off Apple’s MSRP, with prices starting at only $999. These are the same iMacs sold by Apple in their retail... Read more
Save $100 on the 13″ 1.4GHz MacBook Pro at th...
Apple resellers have 13″ 1.4GHz MacBook Pros on sale today for $100 off Apple’s MSRP, and some are including free overnight delivery: (1) Amazon has new 2019 13″ 1.4GHz MacBook Pros on sale for $100... Read more
AT&T offers free 64GB Apple iPhone XS wit...
Open a new line of service with AT&T, and they will include a free 64GB iPhone XS. Credit for the phone is applied monthly over a 30 month lease. The fine print: “Limited Time Requires new line... Read more
New Verizon deal: Apple iPhone XR for $300 of...
Switch to Verizon and sign up with one of their Unlimited plans, and Verizon will take $300 off the price of an Apple iPhone XR (regularly $749), plus get a free $200 prepaid Mastercard. This is an... Read more
Amazon’s popular AirPods sale is back with mo...
Amazon has new 2019 Apple AirPods on sale today ranging up to $40 off MSRP, starting at $129, as part of their popular Apple AirPods sale. Shipping is free: – AirPods Pro: $234.98 $15 off MSRP –... Read more
Apple’s top of the line 10.5″ 256GB WiFi + Ce...
B&H Photo has the top of the line 10.5″ 256GB WiFi + Cellular iPad Air on sale for $599 shipped. That’s $180 off Apple’s MSRP for this model and the cheapest price available. Overnight shipping... Read more
Apple’s refurbished iPad Pros are the cheapes...
Apple has Certified Refurbished 11″ iPad Pros available on their online store for up to $220 off the cost of new models. Prices start at $679. Each iPad comes with a standard Apple one-year warranty... Read more
Just in: Take $100 off the price of the 3.0GH...
Apple resellers are offering new 2018 6-Core Mac minis for $100 off Apple’s MSRP today, only $999. B&H Photo has 6-Core Mac minis on sale for $100 off Apple’s standard MSRP. Overnight shipping is... Read more
Apple has 4-core and 6-core 2018 Mac minis av...
Apple has Certified Refurbished 2018 Mac minis available on their online store for $120-$170 off the cost of new models. Each mini comes with a new outer case plus a standard Apple one-year warranty... Read more
Amazon offers $200 discount on 13″ MacBook Ai...
Amazon has new 2019 13″ MacBook Airs with 256GB SSDs on sale for $200 off Apple’s MSRP, now only $1099, each including free shipping. Be sure to select Amazon as the seller during checkout, rather... Read more

Jobs Board

Tableau Data Visualization Engineer - *Apple...
Job Summary Apple is looking for a seasoned Tableau Data Visualization Engineer to join the team on an initial 9 month contract at our Global HQ in Cupertino. The Read more
*Apple* Mobility Pro - Best Buy (United Stat...
**744429BR** **Job Title:** Apple Mobility Pro **Job Category:** Store Associates **Store NUmber or Department:** 000574-Garner-Store **Job Description:** At Best Read more
Geek Squad *Apple* Consultation Professiona...
**757963BR** **Job Title:** Geek Squad Apple Consultation Professional **Job Category:** Store Associates **Store NUmber or Department:** 000433-Henrietta-Store Read more
*Apple* Computing Professional - Best Buy (U...
**754611BR** **Job Title:** Apple Computing Professional **Job Category:** Store Associates **Store NUmber or Department:** 000142-Milpitas-Store **Job Read more
Best Buy *Apple* Computing Master - Best Bu...
**745058BR** **Job Title:** Best Buy Apple Computing Master **Job Category:** Store Associates **Store NUmber or Department:** 001080-Lake Charles-Store **Job Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.