TweetFollow Us on Twitter

PowerPlant Debugging Classes

Volume Number: 15 (1999)
Issue Number: 5
Column Tag: PowerPlant Workshop

PowerPlant's Debugging Classes

by John C. Daub, Austin, Texas USA

Techniques and tools to help you find and prevent bugs

What We Have Here is a Failure To Deallocate

That line comes from infamous Coolhand Leak (see the help text for the "leaks" 'dcmd'). And like it or not, things like this - bugs - happen. Humans write software, by nature humans make mistakes, so it's a fair bet that there will be mistakes (bugs) in software. Of course no one likes bugs, especially the users of our software, so it behooves us programmers to do our best to write solid and bug-free code. I've found three stages in which the programmer can work to make their code bug free: before, during, and after coding.

Before coding requires proper planning and design in terms of interfaces, implementation, tool selection, and so on. Some would argue this stage is most important as starting off on the wrong foot is more difficult to recover from down the road. During coding involves techniques such as performing assertions to validate arguments and return values, checking for nil, and other processes that you can perform while typing code. After coding involves such things as running under a debugger or stress-testing/validation tool (such as QC or Spotlight), or worst case, receiving a bug report from a user.

The core of PowerPlant mostly offers tools for the "during" stage. Looking in UDebugging and UException, you find the core elements for checking errors, throwing exceptions, and performing Signals (informational messages). These tools provide a good foundation to help you write more solid code, but certainly more can be done. Enter the Debugging Classes.

The Debugging Classes are a fairly recent addition to PowerPlant. They debuted on CodeWarrior Professional 3, but I wasn't happy with their implementation. I have since rewritten the classes, and the fruits of this labor can be seen on Pro 5, which should be on your desk by the time you read this article. In this article, I'd like to introduce you to the Debugging Classes and the wonderful tools they have to offer towards helping you write better code, squash any bugs you may find, and hopefully prevent bugs from happening in the first place. The Debugging Classes don't offer much to help with the "before" stage (aside from the fact you should choose to use them), but they do provide a plethora of tools for the "during" and "after" stage. The Debugging Classes are considered "Advanced Classes," so if you are a PowerPlant newbie, you may wish to get better acquainted with the core and basics of PowerPlant first. But do return to look at the Debugging Classes eventually - they'll help you write better code in the long run. Without further ado, let's dig in!


The Debugging Classes were written with a few chief goals in mind: to be drop and play, to be flexible, and to be simple yet powerful. The classes needed to be as "drop and play" as possible; that is, they needed to be designed so they could be added to (or removed from) an existing project with minimal effort. The classes are not integrated throughout PowerPlant (at least at this stage) to avoid dependencies upon the classes. This was important as existing projects may have their own debugging mechanisms. It also provides a means for users to try out the classes on their existing project, but if they determine they aren't right for the job, they can easily be removed. Theoretically, to add the classes to an existing project, all one has to do is add the files from the _Debugging Classes folder to a project/target, establish a few macros for third party supports (as laid out in PP_Debug.h), then call LDebugMenuAttachment::InstallDebugMenu() from their Application's Initialize() method:

   #if PP_Debug

There are other means of instantiating the Debug menu as well as overall use of the Debugging Classes, but for the newcomer, this is the best place to start.

The Debugging Classes were also designed to be as flexible as possible. When I first wrote the classes, I generated everything at runtime: the windows, the menus, the behaviors. This was done to minimize impact and conflicts with existing projects. However, this method turned out to be less than optimal as it didn't provide a simple means of customization, and it also tied the user to the implementation provided by the Factory (pun intended). For the Pro 5 version of the classes, I removed all of the on-the-fly creation and instead used the tried-and-true Mac method of using Resources. By using Resources, the code is cleaner, the code is smaller, and it's easier to customize. The one downside is the potential for Resource ID's to conflict. To work around this possibility, one can use the factory Resources as a template for your own custom versions. Then when creating the Debug menu, one can fill out an SDebugInfo structure with the relevant information about the Resources. For example, the default 'MENU' ID for the Debug menu is 600. If instead you wished to use 1000, you could create the Debug menu like this:

   #if PP_Debug
      SDebugInfo      theDebugInfo;

      theDebugInfo.debugMenuID = 1000;

      mDebugAttachment = new



Slightly more code than the previous snippet, but it allows for greater flexibility in the long run. Don't worry if you don't understand everything that's going on just yet. By the end of this article things should look a little more familiar.

Another item of flexibility is the extensive use of macros throughout the classes. The macros are designed to be the point of entry to the Debugging Classes within your code. These macros toggle their behavior based upon the nature of your target: debug build or release/final build. This way you can write your code once, gain full debug features in your debug builds, but have the code stripped out or reverted to a "clean, release" version of the functionality for you release builds. So instead of doing this:

   #if PP_Debug
      LPane*         thePane = theWindow->FindPaneByID(1);
      LCaption*   theCaption = dynamic_cast<LCaption*>(thePane);
      LCaption*   theCaption = dynamic_cast<LCaption*>

you can instead use one of the Debugging Classes macros:

      LCaption*   theCaption =
                  FindPaneByID_(theWindow, 1, LCaption);

You can find FindPaneByID_ and other useful macros in PP_DebugMacros.h, as well as throughout many of the header files like UOnyx and UDebugNew.

The third goal of the classes was to be as simple as possible, yet as powerful as possible. There is a great deal of code involved in the classes, but most of this code you never have to interact with directly. The Tree classes provide a dynamic runtime display of the Commander Chain and Visual Hierarchy. There are many classes and a lot of code to make this magic possible, but all you have to do is select Show Command Chain or Show Visual Hierarchy from the Debug menu - the details are handled for you automatically. Furthermore, if something is better handled by another tool, the Debugging Classes strive to work that tool into PowerPlant instead of reinventing the wheel. UOnyx provides a PowerPlant-savvy interface to Onyx Technology's QC and Spotlight tools. UDebugNew provides a wrapper to DebugNew (a tool for validating C++ pointers), and works with UOnyx to help DebugNew and Spotlight play nice together.

Of course, a final goal of the classes is to help you write better code, and diagnose and fix problems. Now that you've gotten a taste of the classes, let's take a look at the specifics of what the Debugging Classes have to offer.

What's In There?

Support Classes

If you're unfamiliar with the Debugging Classes, you're probably wondering what this Debug menu is. The Debug menu, as implemented by LDebugMenuAttachment, is a special menu added to your Application's MenuBar that provides you with runtime access to many of the Debugging Classes runtime features.

Figure 1. The Debug menu from LDebugMenuAttachment.

The Debugging Classes are designed with the Debug menu as the central point. You don't have to use LDebugMenuAttachment to use the Debugging Classes (many of the classes can be used independently), but LDebugMenuAttachment certainly facilitates things - again I would recommend newcomers to start here and work on customization after you're more familiar with the classes.

From the Debug menu, you can: break into a Debugger; launch helper applications like ZoneRanger (on the CW Pro Mac Tools CD) or HeapBoss (from Biit, Inc); display the Command Chain and Visual Hierarchy (Tree Classes); perform heap manipulations (compact, purge, scramble, via UHeapUtils and LHeapAction); interact with DebugNew (UDebugNew); interact with QC (UOnyx); manipulate the values of gDebugThrow and gDebugSignal (UDebugging); consume memory (UMemoryEater); and validate your PPob Resources (UValidPPob). One of the advantages to the menu is that some of these values normally have no runtime interface, e.g. gDebugThrow/gDebugSignal or DebugNew; to manipulate these values you have to change your code, recompile, and re-run. However through the Debug menu, you can manipulate these values at runtime with no need to recompile your project/target.

Another part of the Support Classes is LHeapAction. LHeapAction is a Periodical object that performs certain actions on a given heap (typically the Application's heap). These actions include compacting, purging, compacting and purging (at the same time), and if QC support is enabled, performing a heap consistency check, bounds checking, and a heap scramble. You can access these actions and modify their frequency via the Debug menu.

Figure 2. HeapAction submenu.

To perform such actions on your heap, either immediately or periodically, is a boon towards helping you locate stale Handle usage, avoiding problems with cached Resources, and overall stress-testing your Application.

Stream Classes

There's actually only one Stream Class, LDebugStream, but the utility of this class cannot be underestimated. Those of you that use the "debugging by printf" technique will find LDebugStream a useful feature. LDebugStream is a Stream class that sends data to a debugging location. This location (EFlushLocation) can be a debugger, a file, the mechanism used by gDebugThrow or gDebugSignal, or to a console such as the SIOUX console window (the ability to flush to a console is new in Pro 5). One item of note is that LDebugStream does not inherit from LStream; this is intentional as an LStream can be two-ways (in and out), but LDebugStream is one-way (out, to the EFlushLocation). Furthermore, LStream is oriented towards binary streams, whereas LDebugStream outputs ASCII text.

LDebugStream provides many methods and operator overloads to ease streaming. There are numerous Write methods for many data types both basic (integers, bool's) and Mac-specific (Rect, Point, RGBColor, RgnHandle, FourCharCode, NumVersion, Fixed). When these data types are written, they are written in a useful human-readable manner. For example, outputting a Point would generate the line:

   Point - v: 15 h: 20

LDebugStream also provides detailed information about raw Handle's and Ptr's via the Dump methods. These Dump methods were introduced in Pro 5, and not only provide a raw look at the memory, but also useful information about the memory, especially useful with Handle's. A DumpHandle_() of STRx_Standards yields this result:

"PP Debug Tester DEBUG PPC" debug log for Sun, Mar 7, 1999 4:23:13 PM

Results of Handle dump. FILE: "CDebugApp.cp" LINE: 347
   Address: 0x1E30BA4 | Master pointer: 0x1E47F40 |          Handle data size: 97 | State: UPR
   Resource Info - Type: 'STR#' ID: 200 Name: Standards
   Resource Attributes - SysRef: OFF SysHeap: OFF          Purgeable: ON Locked: OFF Protected: 
      OFF Preload: OFF Changed: OFF
Results of Raw dump. FILE: "CDebugApp.cp" LINE: 347
   Dumping 97 bytes of memory starting at address:          0x1E47F40
   OFFSET     | CONTENTS (HEX)                          | CONTENTS (ASCII)
   0x00000000 | 0004 1644 6562 7567 6769 6E67 2043 6C61 | ...Debugging Cla
   0x00000010 | 7373 6573 2044 656D 6F0D 5361 7665 2046 | sses Demo.Save F
   0x00000020 | 696C 6520 4173 3A1C 4F70 656E 3A20 4465 | ile As:.Open: De
   0x00000030 | 6275 6767 696E 6720 436C 6173 7365 7320 | bugging Classes 
   0x00000040 | 4465 6D6F 1C53 6176 653A 2044 6562 7567 | Demo.Save: Debug
   0x00000050 | 6769 6E67 2043 6C61 7373 6573 2044 656D | ging Classes Dem
   0x00000060 | 6F                                      | o               
End Raw dump. FILE: "CDebugApp.cp" LINE: 347

End Handle dump. FILE: "CDebugApp.cp" LINE: 347

In this dump you can see information such as the address of the Handle and its master pointer, the size of the Handle, its state (lock, purgable, resource), and the raw memory contents. As well, if the Handle is a Resource Handle, information about the Resource and its attributes are listed for your edification. Notice as well that DumpHandle_() is a macro. As was mentioned previously, the Debugging Classes provide macros for ease of use. See LDebugStream.h for more DebugStream macros.

Tree Classes

The Tree Classes are one of the niftier portions of the Debugging Classes, as well as the most common reason for PowerPlant users to start using the Debugging Classes (since everyone seems to run into a Commander Chain problem sooner or later). Long long ago in a cubicle far far away from mine, Greg Bolsinga (Metrowerks' Class Wrangler Wrangler) had problems with his Commander Chain. He hacked up a utility that would display the Commander Chain in a Pane at runtime. Since it helped him solve his problem, Greg passed his (admitted) hack along to me to see what we could do with it officially for PowerPlant. We placed it on CW Pro 2 as an example, but there the seed was sown for the Debugging Classes. Since that time, LCommanderTree has been cleaned up and fleshed out with more functionality than the original, abstracted back to a more common base class (LTree), and from there subclassed to also provide information about the Visual Hierarchy (LPaneTree). In addition to displaying the Visual Hierarchy of the frontmost regular or modal window, LPaneTree also displays Attachment and Broadcaster/Listener information.

Figure 3. LCommanderTree and LPaneTree in action.

Looking at Figure 3 you can see the Trees display a great deal of information about the respective Tree. First, each LTreeWindow contains a set of controls across the top to allow you to manipulate the Tree/Window's behavior. You can set the Tree to automatically refresh at a certain interval (this interval is currently set via the Debug menu), or to refresh immediately. You can save the current Tree to a file (internally using LDebugStream), and you can also toggle the extra information (such as the Attachment and Broadcaster/Listener information) on and off as it is optional information and can clutter the screen.

The CommanderTree provides you with a visual representation of your Application's Commander Chain. Each level of indentation represents a level down the chain, and only objects inheriting from LCommander are displayed. For each object, its name is given as well as its Commander duty state. If the object is also a Pane, it's PaneIDT is listed. Text styles are used to designate the on-duty chain, the target, and any latent Commanders; the styles are bold, red color, and italics, respectively, by default, but you can customize these styles as you wish.

The PaneTree provides you with a representation of the Visual Hierarchy of the frontmost window in the regular or modal layer (floating windows are not supported by default as targeting floaters is tricky to do). Basic Pane information is provided, such as object name, PaneIDT, state (active, enable, visible), and descriptor. If you turn on the display of extra information, any Attachments on the Pane will be listed (along with basic Attachment information such as its Message and the value of mExecuteHost). If the Pane is a Broadcaster its Listeners will be listed, and if the Pane is a Listener its Broadcasters will be listed. One additional feature of LPaneTree is that the (deepest sub-) Pane currently being moused over will be colored in green (by default, user customizable) to aid in identifying Panes at runtime - especially useful if you create your Views on the fly.


There are three header files used throughout the Debugging Classes: PP_Debug.h, PP_DebugConstants.h, and PP_DebugMacros.h. PP_Debug.h is akin to PP_Prefix.h in that every file in the Debugging Classes somehow #includes this file. It is also similar to PP_Macros.h in that PP_Debug.h contains the macros used to establish the state of feature support within the Debugging Classes; this mostly pertains to third party supports (QC, Spotlight, MoreFiles, DebugNew). PP_DebugConstants.h contains the constants used by the Debugging Classes. Most of this file you do not need to concern yourself with, however one item of note is that the CommandT range of 600-799 inclusive is reserved for use by the Debugging Classes. Fortunately, this range is within the range of PowerPlant's reserved CommandT's (-999 to 999 inclusive) so you shouldn't run into any conflicts.

The PP_DebugMacros.h file is certainly the most interesting file of the three global headers. Within this file are many useful macros that you can and should use throughout your code. There are validation macros: ValidatePtr_(), ValidateHandle_(), ValidateObject_(), ValidateSimpleObject_(). These validation macros ensure the given variable is valid by performing nil checks and using QC and DebugNew if those supports are enabled. You should use these macros whenever you allocate memory/objects or when the state of memory/object could be in question. Also within the file are assertion macros: AssertHandleLocked_() ensures the given Handle is locked, AssertHandleUnlocked_() ensures the given Handle is unlocked, AssertHandleResource_() ensures the given Handle is a Resource Handle, and AssertHandleMemory_() ensures the given Handle is a Memory Handle. As these macros are assertions, they will be preprocessed out of release/final builds. The Verify_() macro used to be a synonym for Assert_(), but in Pro 5 its behavior changed slightly. It still performs an assertion, but now the Verify_() statement is not preprocessed away in release/final builds. The DisposeOf_() suite of macros are used in place of delete. In debug builds, the pointer is validated, delete is called, and the pointer variable is set to nil; in release/final builds, the pointer is deleted and the variable set to nil.

Although the Debugging Classes are currently and mostly separate from the rest of PowerPlant, certain ideas have found their way into the core of PowerPlant. One of these are the Suppression macros: StDisableDebugThrow_(), StDisableDebugSignal_(), StChangeDebugThrow_(), and StChangeDebugSignal_(). These macros temporarily modify the EDebugAction of gDebugThrow or gDebugSignal. The Disable macros set the EDebugAction to debugAction_Nothing, and the Change macros set the EDebugAction to whatever new EDebugAction is specified. You'd want to use these macros in situations where a Throw_() or Signal_() might occur but you don't want PowerPlant's UDebugging mechanisms to kick in.

   try {

         // This will ThrowIfOSErr_(memFullErr); if we
         // run out of memory.
   } catch (LException& iErr) {

            // No problems. Running out of memory isn't
            // fatal.
      if (iErr.GetErrorCode() != memFullErr) {
         throw;      // rethrow

In the above snippet, I know it's possible to run out of memory. I want this situation to be handled and the exception to still be thrown, but I don't want to hear about it (I don't want to break into the debugger or have the Throw 'ALRT' displayed). By using StDisableDebugThrow_() the UDebugging functionality is temporarily suppressed. It is important to note the "St" designation of the macros - they do behave like stack-base classes; in fact, they use StValueChanger (UMemoryMgr.h) to accomplish their task.

Finally, PP_DebugMacros.h contain some useful macros that replace the tedium of FindPaneByID and dynamic_cast's. Typically one calls FindPaneByID() along these lines:

   LCaption* theCaption = dynamic_cast<LCaption*>

This code sequence does work, but there is a hidden chance for failure: if FindPaneByID() does not find the Pane it returns nil, and then the dynamic_cast will fail as well (although it is safe to dynamic_cast a nil pointer). The problem is that you cannot tell from the ThrowIfNil_() if the failure was due to FindPaneByID() failing or the dynamic_cast failing. FindPaneByID_() alleviates this ambiguity by first performing a FindPaneByID() and validating that result. If the result is good, then the dynamic_cast is performed and that result is validated as well. Along the way, any failures are noted for exactly the source of the failure to help you better pinpoint the source of the failure. The improved code is:

   LCaption*   theCaption =
                  FindPaneByID_(theWindow, 1, LCaption);

There is also a FindPaneByIDNoThrow_() variant that raises a Signal instead of Throwing, and returns nil upon failure.

The DebugCast_() and DebugCastNoThrow_() macros perform a dynamic_cast of one pointer to another (it does not handle dynamic_cast'ing of references). They validate the arguments and report the error by Throwing or Signaling. These four macros not only provide a more robust means of performing their functionality, but it's a lot easier to type the one line of code. :-)


This portion of the Debugging Classes is fairly straightforward. DebugTrees.CTYP contains the CTYP's for the Tree classes (LTree, LPaneTree, LCommanderTree, LTreeWindow). If it's not already there, place this file into the Custom Types folder within the Metrowerks PowerPlant folder of your CodeWarrior installation (this is the same folder where the Constructor application resides). It is not essential to add this file to your project/target, but you're welcome to do so if you wish to include the 'CTYP' Resources in your binaries.

PP Debug Support.ppob and PP Debug Support.rsrc contain vital Resources used by the Debugging Classes. PP Debug Support.ppob file contains the default 'PPob', 'MENU', and 'Txtr' Resources used by the various c lasses. You can add this file as-is to your project/target, or you can copy the Resources to your own file and customize them as you wish. PP Debug Support.rsrc contains the nifty debug icon used as the menu title for the Debug menu (optional, cosmetic) and contains replacement Resources for the ThrowAt and SignalAt alerts (as found in PP DebugAlerts.rsrc). These replacement Resources are used in conjunction with UDebuggingPlus.cp, which we'll discuss in the next subsection. You're welcome to use the Resources as-is or customize them as you wish.

Utility Classes

The Debugging Classes contain many utility classes and namespaces to help in your coding efforts. UDebuggingPlus.cp is a replacement for UDebugging.cp. Both files implement the UDebugging namespace, but only one file can be within your project at a time (this is akin to how UDesktop.cp and UFloatingDesktop.cp work). Before Pro 5, UDebugging's ThrowAt and SignalAt alerts (as found in PP DebugAlerts.rsrc) would display the alert, and the only action you could take in response to the alert was to click OK and proceed in whatever manner the flow of the code would take you. This wasn't always optimal. UDebuggingPlus.cp (and PP Debug Support.rsrc) were written to provide you with greater options upon receiving the ThrowAt or SignalAt alerts.

Figure 4. Improved SignalAt alert.

In Figure 4 you can see the additional options provided by the improved UDebuggingPlus. Continue did just that - continue execution. Quit immediately calls ExitToShell. Debugger breaks into a debugger, Quiet changes the respective EDebugAction to debugAction_Nothing, and Log outputs the data from the Signal or Throw to a file via LDebugStream. Furthermore, the whitespace given to display the condition/error code is larger than the original alerts to allow for more error text. Although Figure 4 shows the SignalAt alert, the ThrowAt alert is the same in terms of functionality.

As of Pro 5, UDebugging and PP DebugAlerts.rsrc now support most of the functionality provided by UDebuggingPlus/PP Debug Support.rsrc. However, as of this writing, the Log functionality is missing. When all of UDebuggingPlus' functionality is moved into UDebugging, UDebuggingPlus will be obsoleted.

UDebugNew provides a wrapper for DebugNew, mostly to enable DebugNew and Spotlight to work together (as DebugNew does funky yet kosher things that Spotlight would otherwise complain about). UDebugNew also contains various macros to facilitate using DebugNew in your code, interfaces are given to aspects of DebugNew that don't have interfaces, removes the tedium of remembering what is and is not supported in DebugNew based upon the setting of DEBUG_NEW, and provides a more PowerPlant-savvy error handler. As of this writing Metrowerks is working on a replacement and improvement for DebugNew called DebugMem. Eventually support for DebugMem will be added to the Debugging Classes, but this support is not part of Pro 5.

UDebugUtils is a collection of sundry utilities. CheckEnvironment() examines your environment at runtime and alerts you to any potentially problem situations, such as not having a debugger installed. It is not required to call CheckEnvironment(), but it is highly recommended to do so. A good place to call it is immediately after Toolbox initialization. Debugger() and DebugStr() are replacements for the Toolbox traps of the same name. These versions however check for the presence of a debugger before calling the Toolbox trap to avoid any ugly crashes. UDebugUtils.h contains wrapper macros for the Debugger traps: PP_Debugger_() and PP_DebugStr_() go through the UDebugUtils bottlenecks, and Debugger_() and DebugStr_() call straight to the Toolbox. The advantage of these macros is that they will be preprocessed out of final/release builds. How many times have you inadvertently left a DebugStr call in your release builds?

UHeapUtils provides means for manipulating heaps. You can compact, purge, and scramble your heaps. Compacting and purging is accomplished through Toolbox routines, but scrambling is a bit odd. If QC is present, then QC's scrambling mechanisms are used. But if QC is not present, DebugStr's are used to drop into MacsBug to use its heap scrambling functionality. It's a little ugly, but it works. There's no excuse not to scramble your heap as it will sooner or later turn up problems (don't forget about LHeapAction).

UMemoryEater helps you simulate low-memory situations by consuming memory.

Figure 5. Eat Memory dialog.

When you select Eat Memory... from the Debug menu, the dialog in Figure 5 is displayed. You can specify the number of bytes to eat and what type of memory to eat: Handle (relocatable) or Ptr (non-relocatable). This functionality is best used with ZoneRanger to keep an eye on the exact state of your heap as you consume memory. It is important to test your Application's functionality in low-memory situations. LGrowZone can help, but it is only one part of a good low-memory handling strategy.

UOnyx provides wrappers for Spotlight and QC from Onyx Technology. Use of UOnyx is optional, which is important if you do not own QC and/or Spotlight. The key features of UOnyx are the famous macros to aid in supporting QC/Spotlight in debug builds but is removed from release builds, and wrappers for the QC API to facilitate its ease of use and make it more PowerPlant-savvy. The QC and Spotlight products and API's are not provided by Metrowerks; you must purchase these products separately from Onyx Technology.

UProcess is a wrapper for the Process Manager that strives to make using the Process Manager a bit easier. This class can be used independent of the Debugging Classes, as its functionality certainly extends beyond the bounds of debugging. UVolume contains utility functions for working with volumes. It is not a complete class by any means. UVolume (and UProcess as well) were actually written to aid in the implementation of LDebugMenuAttachment's feature for launching ZoneRanger and HeapBoss. See UVolume::FindApp() and UProcess::LaunchApp() to see how these fit together.

Finally, UValidPPob provides a means for validating the data within your 'PPob' Resources.

Figure 6. Validate PPob dialog.

Currently it looks at what classes are within a specified PPob (specified by the dialog in Figure 6), compares this list to the URegistrar table, and any unregistered classes are reported via a Signal_(). A ValidateAllPPobs() method is provided as well to validate every PPob, and the results of this validation are streamed to a file via LDebugStream. Currently UValidPPob can only list what is in a PPob but not registered. The other direction, listing what is registered but not in any PPob ("over-registration") cannot be cleanly done. One key reason is the Appearance Classes, which register the Implementation classes but these classes never appear in any PPob DataStream.

Project Stationery, Sample Code, & Documentation

The last part of the Debugging Classes are non-source code support files. For Pro 5, the PowerPlant project stationery has been revamped. The old standbys of Basic, Document, Appearance, and Network remain, and a new "Advanced Stationery" has been introduced. This stationery is geared towards the serious new project. It includes most of the core PowerPlant files, Thread Classes, Table Classes, Appearance Classes, and of course the Debugging Classes. The project and default sources are also set for debug and release targets. Debug targets turn compiler optimizations off and debug information on, while release targets turn compiler optimizations on and debug information off. The default Application object class contains a fair amount of debugging infrastructure to help you get started, using the Debugging Classes and MetroNub Utilities (see the (Debugger Extras) folder in your CodeWarrior install). One extra file in the Advanced Stationery is PPDebug_New.cp. This file implements global replacements for all variants of operators new and delete. These implementations utilize DebugNew and the Debugging Classes to make the operators more robust and better integrated with PowerPlant and your project. Also provided is PP_NewHandler(), a PowerPlant-savvy C++ new_handler (see § in the C++ language standard).

Also new in Pro 5 is documentation on the Debugging Classes. A chapter on the Debugging Classes has been added to the PowerPlant Advanced Topics manual. You've probably noticed this article does not contain any tutorials nor in-depth HOWTO's for using the Debugging Classes. This was an intentional decision as the chapter and its accompanying example code do a good job to get you going in using the Debugging Classes. If this article has sparked your interest in these classes, your next stop should be reading this chapter and doing its example code.


I'd like to briefly touch on the subject of customizing the classes. Before you consider customizing the classes, first take the time to familiarize yourself with the classes and tools as provided from the Factory. I tried to minimize the need for customization, so try out the defaults and find what works for you and what you might wish to improve upon.

One area that I personally would customize is the Debug menu itself. The most useful customization might be adding keyboard shortcuts to commands you frequently use, as always going to the menu can be a bit tedious (I'm one of those people that prefer the keyboard over the mouse). Another might be adding your own commands to the menu to help you execute test code or start a specific chain of events. Regardless of what you do, don't modify the default Resources and Resource/source files. Instead, make copies of the relevant Resource or subclass the sources local to your project and modify those instead. Better still, consider making your own project stationery that contains all of your customizations so every new project you create will be established just as you like it from the onset.


The Debugging Classes shipped in the _In Progress folder on CodeWarrior Professional 5, but the classes are fairly robust and stable. I do not anticipate a great deal of changes to them in the future. Certainly rough edges will be smoothed, user feature requests will be considered, and any bugs found (heaven forbid ;-) will of course be fixed. One outstanding issue is the integration of the classes throughout the core of PowerPlant; the jury is still out on this one. The classes will need to fully stabilize first as well as weighing the potential impact integration could have upon existing source bases. I'd also like to see about adding supports for more third party products, such as HeapManager. Of course these are all hopes and dreams and by no means constitute any sort of promise nor guarantee they actually will happen (although I hope they will :-).

One point of definite uncertainty is how the Debugging Classes will evolve in terms of Carbon and Mac OS X. Some of the Debugging Classes technology is centered around the Mac OS of today, both in terms of low-level supports, like UDebugUtils, and higher-level assumptions, like UHeapUtils. Some classes should go across with no problems (Trees), some may need to be modified slightly (the Raw methods in LDebugStream), some may become moot (UHeapUtils), and others are totally unknown at this time (UDebugUtils). We'll just have to wait and see how Carbon and OS X shape up before the fate of the Debugging Classes can be fully determined.


I hope you've enjoyed this article on the PowerPlant Debugging Classes. They've certainly been one of the most fun bits of PowerPlant I've written, and IMHO one of the more useful. If you haven't used the Debugging Classes before, please do give a read over their chapter in the Advanced Topics manual and give them a try. If you have used the Debugging Classes, try out an aspect that you may not have used yet, like the various macros. And if you wish, feel free to email me with any stories of how the Debugging Classes helped you, feature requests, bug reports, and even flames (but I hope there aren't many of those).

Good luck, happy programming, and I hope you find the Debugging Classes a helpful, useful, and essential part of your toolbox.


John C. Daub spends a lot of time working on PowerPlant. When he's not writing code for Metrowerks, he writes a lot of his own PowerPlant classes for the Contributed Class archives. John's seen a lot of code in his days, and they are part of the inspiration behind the Debugging Classes. John is also still using System 7.6.1 at home, so please don't complain about the screenshots. You can reach John at


Community Search:
MacTech Search:

Software Updates via MacUpdate

Viber 11.9.1 - Send messages and make fr...
Viber lets you send free messages and make free calls to other Viber users, on any device and network, in any country! Viber syncs your contacts, messages and call history with your mobile device, so... Read more
Vallum 3.3.2 - $15.00
Vallum is a little tool that helps you monitor and block apps connections and throttle apps bandwidth. It is able to intercept connections at the application layer, and hold them while you decide... Read more
Microsoft OneNote 16.31 - Free digital n...
OneNote is your very own digital notebook. With OneNote, you can capture that flash of genius, that moment of inspiration, or that list of errands that's too important to forget. Whether you're at... Read more
Apple Pages 8.2.1 - Apple's word pr...
Apple Pages is a powerful word processor that gives you everything you need to create documents that look beautiful. And read beautifully. It lets you work seamlessly between Mac and iOS devices, and... Read more
Numbers 6.2.1 - Apple's spreadsheet...
With Apple Numbers, sophisticated spreadsheets are just the start. The whole sheet is your canvas. Just add dramatic interactive charts, tables, and images that paint a revealing picture of your data... Read more
f.lux 39.9873 - Adjusts the color of you...
f.lux makes the color of your computer's display adapt to the time of day, warm at night and like sunlight during the day. Ever notice how people texting at night have that eerie blue glow? Or wake... Read more
Deeper 2.5.0 - Enable hidden features in...
Deeper is a personalization utility for macOS which allows you to enable and disable the hidden functions of the Finder, Dock, QuickTime, Safari, iTunes, login window, Spotlight, and many of Apple's... Read more
NTFS 15.5.71 - Provides full read and wr...
NTFS breaks down the barriers between Windows and macOS. Paragon NTFS effectively solves the communication problems between the Mac system and NTFS. Write, edit, copy, move, delete files on NTFS... Read more
MTR - The Mac's oldest and...
MTR (was MacTheRipper)--the Mac's oldest and smartest DVD-backup app. MTR - the complete toolbox, not a one-trick, point-and-click extractor. MTR is intended for making fair-use, backup copies of... Read more
Keynote 9.2.1 - Apple's presentatio...
Easily create gorgeous presentations with the all-new Keynote, featuring powerful yet easy-to-use tools and dazzling effects that will make you a very hard act to follow. The Theme Chooser lets you... Read more

Latest Forum Discussions

See All

Black Desert Mobile gets an official rel...
Pearl Abyss has just announced that its highly-anticipated MMO, Black Desert Mobile, will launch globally for iOS and Android on December 11th. [Read more] | Read more »
Another Eden receives new a episode, cha...
Another Eden, WFS' popular RPG, has received another update that brings new story content to the game alongside a few new heroes to discover. [Read more] | Read more »
Overdox guide - Tips and tricks for begi...
Overdox is a clever battle royale that changes things up by adding MOBA mechanics and melee combat to the mix. This new hybrid game can be quite a bit to take in at first, so we’ve put together a list of tips to help you get a leg up on the... | Read more »
Roterra Extreme - Great Escape is a pers...
Roterra Extreme – Great Escape has been described by developers Dig-It Games as a mini-sequel to their acclaimed title Roterra: Flip the Fairytale. It continues that game's tradition of messing with which way is up, tasking you with solving... | Read more »
Hearthstone: Battlegrounds open beta lau...
Remember earlier this year when auto battlers were the latest hotness? We had Auto Chess, DOTA Underlords, Chess Rush, and more all gunning for our attention. They all had their own reasons to play, but, at least from where I'm standing, most... | Read more »
The House of Da Vinci 2 gets a new gamep...
The House of Da Vinci launched all the way back in 2017. Now, developer Blue Brain Games is gearing up to deliver a second dose of The Room-inspired puzzling. Some fresh details have now emerged, alongside the game's first official trailer. [Read... | Read more »
Shoot 'em up action awaits in Battl...
BattleBrew Productions has just introduced another entry into its award winning, barrelpunk inspired, BattleSky Brigade series. Whilst its previous title BattleSky Brigade TapTap provided fans with idle town building gameplay, this time the... | Read more »
Arcade classic R-Type Dimensions EX blas...
If you're a long time fan of shmups and have been looking for something to play lately, Tozai Games may have just released an ideal game for you on iOS. R-Type Dimensions EX brings the first R-Type and its sequel to iOS devices. [Read more] | Read more »
Intense VR first-person shooter Colonicl...
Our latest VR obsession is Colonicle, an intense VR FPS, recently released on Oculus and Google Play, courtesy of From Fake Eyes and Goboogie Games. It's a pulse-pounding multiplayer shooter which should appeal to genre fanatics and newcomers alike... | Read more »
PUBG Mobile's incoming update bring...
PUGB Mobile's newest Royale Pass season they're calling Fury of the Wasteland arrives tomorrow and with it comes a fair chunk of new content to the game. We'll be seeing a new map, weapon and even a companion system. [Read more] | Read more »

Price Scanner via

New 2019 16″ MacBook Pros on sale for $100 of...
Apple Authorized Reseller Adorama has new 2019 16″ MacBook Pros on sale today for $100 off Apple’s MSRP, each including free shipping. In addition, Adorama charges sales tax for NY & NJ residents... Read more
Apple Watch Series 3 GPS models on sale for l...
Amazon has Apple Watch Series 3 GPS models on sale starting at only $179. There prices are the lowest we’ve ever seen for these models from any Apple reseller. Choose Amazon as the seller rather than... Read more
iOS Bug In Facebook News Feed Lets Device Ca...
NEWS: 11.15.19- Users of the Facebook social media platform’s mobile app running on iOS devices won’t, like, this piece of news one bit in where a bug in the News Feed gave access to the camera... Read more
16″ MacBook Pros on sale! Preorder at Amazon...
Apple’s new 16″ MacBook Pros were only introduced yesterday, but Amazon is already offering a $100 discount on preorders. Prices for the base 6-Core 16″ MacBook Pros start at $2299: – 2019 16″ 2.6GHz... Read more
Use our exclusive MacBook Price Trackers to f...
Our Apple award-winning MacBook price trackers are the best place to look for the best sales & lowest prices on new and clearance MacBook Airs and MacBook Pros–including Apple’s new 16″ MacBook... Read more
New November Verizon iPhone deal: Get an iPho...
Verizon has the 64GB iPhone Xr on sale for 50% off for a limited time, plus they will include a free $200 prepaid MasterCard and a free Amazon Echo Dot. That reduces their price for the 64GB iPhone... Read more
Apple cuts prices on clearance, refurbished 2...
Apple has clearance 2018 15″ 6-Core Touch Bar MacBook Pros, Certified Refurbished, now available starting at only $1829. Each model features a new outer case, shipping is free, and an Apple 1-year... Read more
Up to $450 price drop on clearance 15″ MacBoo...
B&H Photo has dropped prices Apple’s 2019 15″ 6-Core and 8-Core MacBook Pros by $400-$450 off original MSRP, starting at $1999, with free overnight shipping available to many addresses in the US... Read more
Here’s how to save $200 on Apple’s new 16″ Ma...
Apple has released details of their Education discount associated with the new 2019 16″ 6-Core and 8-Core MacBook Pros. Take $200 off the price of the new 8-Core model (now $2599) and $200 off the 16... Read more
Price drop! 2019 15″ 2.6GHz 6-Core MacBook Pr...
Focus Camera has dropped their price for clearance 2019 15″ 2.6GHz 6-Core Space Gray MacBook Pros by $400 to $1999 shipped. Apple’s original MSRP for this model was $2399. Focus charges sales tax for... Read more

Jobs Board

Best Buy *Apple* Computing Master - Best Bu...
**746655BR** **Job Title:** Best Buy Apple Computing Master **Job Category:** Sales **Store NUmber or Department:** 002518-Atlantic Center-Store **Job Description:** Read more
*Apple* Mobility Pro - Best Buy (United Stat...
**744973BR** **Job Title:** Apple Mobility Pro **Job Category:** Store Associates **Store NUmber or Department:** 000949-Rochester Hills-Store **Job Description:** Read more
AV Systems Engineer at *Apple* - Theorem, L...
Job Summary Apple Retail Technology is looking for an Audio Visual Systems Engineer to design and implement scalable, next-generation A/V solutions for Apple ?s Read more
Nurse Practitioner - Field Based (San Bernard...
Nurse Practitioner - Field Based (San Bernardino, CA, Apple Valley, Hesperia) **Location:** **United States** **New** **Requisition #:** PS30312 **Post Date:** 3 Read more
Best Buy *Apple* Computing Master - Best Bu...
**746510BR** **Job Title:** Best Buy Apple Computing Master **Job Category:** Store Associates **Store NUmber or Department:** 001407-Milford-Store **Job Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.