Some useful links on Carbon-related debugging:
The two most powerful techniques for finding memory-related bugs are Guard Malloc and CFZombieLevel.
Guard Malloc can be enabled from Xcode's Debug menu (in Xcode 2.2 or later). This library replaces the system malloc/free, and inserts unmapped pages around allocated blocks. Any attempt to read/write from these areas will instantly cause an exception, and stop you in the debugger at the source of the problem.
Note that Guard Malloc will increase your memory footprint, and is not fully compatible with AltiVec-based code (since allocated blocks may no longer have the expected alignment.
Many APIs are built on top of the CoreFoundation APIs, particularly APIs that provide reference-counted objects. An effective way to track mismanaged references is to enable 'CFZombieLevel'. This can be done with:
$ export CFZombieLevel=65537 $ open /path/to/application.app
This will cause CoreFoundation to scribble over newly allocated or freed memory, which can often provoke a crash if an application is using objects after they have been destroyed. A full list of options can be found in [TN2124].
gcc's STL library supports two #defines to enable additional validation code, to ensure that STL objects are being used correctly. These should be set in Xcode's "Preprocessor Macros" options, or with a .xcconfig file containing:
GCC_PREPROCESSOR_DEFINITIONS = _GLIBCXX_DEBUG _GLIBCXX_DEBUG_PEDANTIC
Unfortunately this extra debug code is not thread-safe (see rdar://4417672 or the gcc [list] and [bug]) in gcc 3.3, and if your application has multiple threads you will be unable to use this feature unless you can require gcc 4.x.
While the application is unresponsive (spinning beachball, rainbow cursor), launch /Applications/Utilities/Activity Monitor.app. Select the unresponsive application in the list of running processes, then choose View -> Sample Process. It will show you the stack trace.