On my Atalasoft blog, I wrote some tips for debugging unmanaged crashes in .NET that I figured out by debugging our .NET Imaging SDK. The idea is the same for iPhone -- namely:
In Xcode, it's actually really easy to get information about how you might be managing memory incorrectly.
Tip 1: Set Deallocated objects to Zombies
Go to Project->Edit Active Executable, go to the Arguments tab and in the environment variables section, add
NSAutoreleaseFreedObjectCheckEnabled
NSZombieEnabled
NSDebugEnabled
And set each to YES. You can leave them there unchecked, but if you check them, then your application will now do some extra checking on autorelease and release and give you a good stack trace when you have done it wrong. A common problem is to think you need to call release when the object is already set to autorelease (see yesterday's post on what the rules are for that).
Tip 2: Enable Guard Malloc
If you think you are having an issue where you go out of bounds of a heap allocated memory block, then in the Run menu, you can check "Enable Guard Malloc". This will tell you if you overrun your bounds. It's not going to be as handy as a Page Heap style check (where each heap allocation gets its own page and therefore crashes at the point of the mistake), but it's better than nothing.
After doing this, you get more capabilities in the debugger. Read this article to see how to use them.
UPDATE: I wrote a much more detailed version of this that focuses onUnderstanding EXC_BAD_ACCESS.
(http://loufranco.com/blog/files/debugging-memory-iphone.html)