iPhone Memory Debugging with NSZombie and Instruments
When your iPhone app crashes with ‘BAD ACCESS’ you’re in trouble – a memory bug where you tried to call a method on a object that was already deleted. Instruments has support for NSZombie – a feature that makes it easy to find the source of the bug by showing you a full history of every alloc, retain, release, and autorelease of the object that caused the crash! Wow. Here’s how:
Basic steps are:
- Run in Performance tool ‘Object Allocations’
- Stop running and set options on ObjAllocations instrument: ‘Enable NSZombie’ Detection and ‘Record Reference Counts’
- Re-run from instruments, when it crashes, click the arrow in the popup zombie dialog
- Open up the stack trace view and see the full memory history of the problem object
- Wow, how awesome is that?
- If you love this post, do me a favor and check out our Free app Focus for Facebook
- You might also like my memory management tutorial and other posts under ‘App Development’.
Here’s a link to the demo program: ZombieDebug Demo Project. The code we’re looking at in the video is:
@implementation ZombieDebugViewController @synthesize objArray; -(void)rewriteText { NSMutableString* s = [NSMutableString stringWithCapacity:100]; for (id obj in objArray) { [s appendFormat:@"%@,\n",obj]; [obj release]; } label.text = s; } - (void)viewDidLoad { [super viewDidLoad]; self.objArray = [NSMutableArray arrayWithCapacity:10]; [objArray addObject:@"I'm a string object"]; [self rewriteText]; } -(IBAction) tapButton:(id)button { NSNumber* n = [NSNumber numberWithLong:random()]; [objArray addObject:n]; [self rewriteText]; } -(void)dealloc { [super dealloc]; self.objArray=nil; } @end









I spent 2 hours yesterday debugging one of these. I honestly had no idea this existed. This is an absolutely amazing tool, thanks for this video!
Thank you, for a very informative demo
Very cool, thanks a lot! I knew of NSZombie but did not know about this cool integration into instruments.
Very interesting, but I can’t make it work in Instruments. Is this a Mac OSX 10.6 / XCode 3.2.1 feature only? I’m running 10.5 and (corresponding latest) XCode 3.1.4.
I’m not sure when this was added to Instruments, it might well be only for the latest version on Snow Leopard. Readon enough to upgrade – this and the static analyser too?
How’d you get the Xcode view you’re using around 40 seconds? That’s so cool with the build results window in the top left. Also, how’d you get the Debugger view in the “Page” toolbar icon in the upper left of your xcode window?
Thats Xcodes All-In-One view. Close your Xcode project but keep the app open. Go to preferences..general. Change Layout. There are 3 alternatives, try them and see what you like.
Bless you, kind sir.
I am weeping tears of joy and gratitude.
:-)
Mark, very nice but I have one question. The NSZombieEnabled check box does not appear if I am debugging on the device. I keep reading it can be done but nothing I’ve tried works. Can you tell me how to enable NSZombie on the device? Thanks!
Hmmm, I don’t know. But… for performance testing you need to test on the device. For memory debugging you don’t need to be on the device. In fact the simulator is much better because of the better workflow speed. Note… if you are having memory problems when the OS sends the low memory warning, you can trigger that yourself from the iPhone simulator apps menu.
The problem only occurs on the device. If I set the NSZombieEnabled YES environment on the executable the debugger will give me the address the message was sent to, but I don’t get debugger console messages with Instruments running. (I could check the device console log I guess) Thanks it’s a great tutorial!
I think this is a great tool, but I ran into two problems…
I couldn’t enable Zombie Detection because it doesn’t work on a device. It only works with the simulator.
My app doesn’t fully function in the simulator because the simulator doesn’t support mail, and I’m also using core data, which is harder to do in a simulator. Therefore, I really need to test on the device, not the simulator. Also, my memory error appears to be coming from taking pictures and sending mail which are not supported on the simulator.
So, I tried this with the simulator anyway, and I got a message about something else… It pointed tok two lines of code that were commented out and it thought that they were each executed twice. I don’t know why I got that data. It seems very strange.
I think this is a very powerful and tremendously useful tool, and I hope to see it working with a device at some point.
I like the video, and especially the screenshots where you clearly describe the steps.
Thanks.
Cool! My guess was that Instruments would allow that easily, but I wasn’t expecting such a simple solution. Thanks for the video :)
I have errors occurring in my process that is on a different thread. I use [NSThread detachNewThreadSelector:... toTarget:self withObject:nil] and I don’t get any calls from NSZombie, and in GDB it doesn’t say EXC_BAD_ACCESS. It just quits. Any help would be appreciated.
Thanks,
Conrad Kramer
email me at: conradkramersapps@gmail.com