TweetFollow Us on Twitter

Debugging Retain Count Bugs

Volume Number: 21 (2005)
Issue Number: 4
Column Tag: Programming

Tips From Big Nerd Ranch

by Aaron Hillegass, Chris Campbell, and Marquis Logan

Debugging Retain Count Bugs

At the Big Nerd Ranch, we teach the world's greatest Cocoa programming course (and the greatest Python, PHP, Perl, and PostgreSQL classes). One of the things that makes the course great is the alumni mailing list. We thought it would be a great service to the larger developer community if we shared some of the tips that have appeared on the list. So each month, we are going to cull through the discussion and publish a few pieces of useful wisdom. This month, we are talking about how to debug errors in the use of retain and release.

Hunting down bugs in your use of retain and release can be very difficult. Before delving into all the ways to find them, let's quickly review the lifetime of an object on the heap. The object is allocated (through the +allocWithZone: method which calls the malloc_zone_calloc() function), it is used, and then it is deallocated (through the -dealloc method which calls the malloc_zone_free() function).

Complicating matters is the retain count. A newly allocated object has a retain count of 1. When an object is retained, the retain count is incremented. When it is released, the retain count is decremented. When the retain count goes to zero, the object is deallocated.

This is complicated even further by the autorelease pool. When an object is sent the message autorelease, it adds itself to the current autorelease pool. When the autorelease pool is deallocated, it send the message release to every object in the pool. In a Cocoa application, the autorelease pool is deallocated after each event is handled.

Use release when possible

Here are two similar erroneous methods:

- (void)bad
{
    NSArray *array = [[NSArray alloc] init];
    [array release];
    [array release];
}

- (void)worse
{
    NSArray *array = [[NSArray alloc] init];
    [array release];
    [array autorelease];
}

The first method is run inside a debugger, it will stop on the erroneous line with a BAD_ACCESS error. The second method will cause a BAD_ACCESS only when the autorelease pool is deallocated. In a large program, it may be difficult to back track to where you autoreleased that object. Using release, besides being more efficient, will make your code easier to debug.

Note that this does not mean that you should break conventions: when creating an object to be vended out, it should be autoreleased:

- (NSNumber *)currentPrice
{
    NSNumber *p = [[NSNumber alloc] initWithInt:(whatTheMarketWillBear - 1)];
    [p autorelease];
    return p;
}

Set Pointers to nil after Objects are Released

To make it impossible to send messages to released objects, set the pointer to nil after the object is released:

- (void)fireThem
{
   [employees release];
   employees = nil;
}

Using Zombies

This code (which uses an object after it has been deallocated) often runs without crashing or throwing exceptions:

- (IBAction)stupidAction:(id)sender
{
    NSMutableString *string = [[nameField stringValue] mutableCopy];
    [string release];
    NSMutableString *anotherString = [NSMutableString stringWithFormat:@"I'm new!"];
    NSLog(@"string = %@", string);
}

The new string object is sometimes created in the same place in memory that the old one had occupied. So, when you run this you sometimes see:

string = I'm new!

On the other hand, sometimes the new string isn't created in the same location and the application crashes with a BAD_ACCESS. As you can imagine, hunting down a bug may or may not rear its ugly head can be maddening.

To debug this code, instead of freeing the memory for reuse, turn the objects into zombies. When you try to use a zombie, Cocoa will throw an exception. Thus, you can consistently reproduce this bug. The trick, then, is to tell Foundation and CoreFoundation, that you want to zombify your objects instead of freeing them.

First, you need to use the debug version of the CoreFoundation framework. To do this, select your executable in Xcode, and in the inspector under the General tab, choose "Use the debug suffix when loading frameworks."

Then, under the Arguments tab, set the environment variable NSZombieEnabled to YES and CFZombieLevel to 5:

Now when you send a message to a released object you will get a nice exception like this:

*** Selector 'respondsToSelector:' sent to dealloced instance 0x328840 of class NSMutableString.

(Remember to disable zombies once the bug is found -- you want the objects to be freed, not zombified in a deployed app.)

Putting a breakpoint on exceptions

Now that you have an exception that is thrown consistently, you will need to create a breakpoint in the debugger where the exception gets raised. Before dealing with the debugger, let's review how exceptions get thrown.

The Cocoa libraries check certain conditions, and if the conditions are not met, they raise exceptions. For example, if you ask for the second item in an array that has only one item, an exception will be thrown. Throwing an exception looks like this:

if (x == 13) {
    NSException *badness = [NSException exceptionWithName:@"BadLuckException"
                                                    reason:@"13 is unlucky"
                                                    userInfo:nil];
    [badness raise];
}

Thus, to stop the debugger as soon as an exception is raised, you can add the breakpoint for -[NSException raise] using the breakpoint panel.

Gradually, Cocoa programmers are moving to the new @throw/@catch/@finally form of exceptions stolen from C++ and Java. In this form, you will throw exceptions like this:

    NSException *badness = [NSException exceptionWithName:@"BadLuckException"
                                                   reason:@"13 is unlucky"
                                                   userInfo:nil];
    
    @throw badness;

(To use new-style exceptions, you must pass the -fobjc-exceptions flag to the compiler.)

To detect when an exception is being thrown from within the debugger, you will want to create a breakpoint on objc_exception_throw().

You will want these breakpoints every time you run the debugger. To automatically add these breakpoints anytime you use gdb, create a .gdbinit file in your home directory and include these lines:

fb -[NSException raise]
fb objc_exception_throw()

Those are the four tips for this week:

  • release instead of autorelease when possible
  • After releasing an object, set pointers to it to nil
  • Use zombies to hunt down retain/release problems
  • Add breakpoints to stop on exceptions

We hope they are useful to you, and we will be back next month with a few more.


Aaron Hillegass, Chris Campbell, and Marquis Logan

 
AAPL
$118.93
Apple Inc.
-0.07
MSFT
$47.81
Microsoft Corpora
+0.06
GOOG
$541.83
Google Inc.
+1.46

MacTech Search:
Community Search:

Software Updates via MacUpdate

Adobe Photoshop Elements 13.0 - Consumer...
Adobe Photoshop Elements 12--the #1 selling consumer photo editing software--helps you edit pictures with powerful, easy-to-use options and share them via print, the web, Facebook, and more.Version... Read more
Skype 7.2.0.412 - Voice-over-internet ph...
Skype allows you to talk to friends, family and co-workers across the Internet without the inconvenience of long distance telephone charges. Using peer-to-peer data transmission technology, Skype... Read more
HoudahSpot 3.9.6 - Advanced file search...
HoudahSpot is a powerful file search tool built upon MacOS X Spotlight. Spotlight unleashed Create detailed queries to locate the exact file you need Narrow down searches. Zero in on files Save... Read more
RapidWeaver 6.0.3 - Create template-base...
RapidWeaver is a next-generation Web design application to help you easily create professional-looking Web sites in minutes. No knowledge of complex code is required, RapidWeaver will take care of... Read more
iPhoto Library Manager 4.1.10 - Manage m...
iPhoto Library Manager lets you organize your photos into multiple iPhoto libraries. Separate your high school and college photos from your latest summer vacation pictures. Or keep some photo... Read more
iExplorer 3.5.1.9 - View and transfer al...
iExplorer is an iPhone browser for Mac lets you view the files on your iOS device. By using a drag and drop interface, you can quickly copy files and folders between your Mac and your iPhone or... Read more
MacUpdate Desktop 6.0.3 - Discover and i...
MacUpdate Desktop 6 brings seamless 1-click installs and version updates to your Mac. With a free MacUpdate account and MacUpdate Desktop 6, Mac users can now install almost any Mac app on macupdate.... Read more
SteerMouse 4.2.2 - Powerful third-party...
SteerMouse is an advanced driver for USB and Bluetooth mice. It also supports Apple Mighty Mouse very well. SteerMouse can assign various functions to buttons that Apple's software does not allow,... Read more
iMazing 1.1 - Complete iOS device manage...
iMazing (was DiskAid) is the ultimate iOS device manager with capabilities far beyond what iTunes offers. With iMazing and your iOS device (iPhone, iPad, or iPod), you can: Copy music to and from... Read more
PopChar X 7.0 - Floating window shows av...
PopChar X helps you get the most out of your font collection. With its crystal-clear interface, PopChar X provides a frustration-free way to access any font's special characters. Expanded... Read more

Latest Forum Discussions

See All

Mystery Case Files: Dire Grove, Sacred G...
Mystery Case Files: Dire Grove, Sacred Grove HD Review By Jennifer Allen on November 28th, 2014 Our Rating: iPad Only App - Designed for the iPad A decent new installment for the popular Mystery Case Files series.   | Read more »
Castaway Paradise – Tips, Tricks, and St...
Ahoy there, castaways: Were you curious about our own thoughts regarding this pristine shipwreck? Check out our Castaway Paradise review! Castaway Paradise is out for iOS, finally giving mobile gamers the opportunity to enjoy the idyllic lifestyle... | Read more »
Castaway Paradise VIP Subs are on Sale f...
Castaway Paradise VIP Subs are on Sale for a Limited Time, and a Special Holiday Update is Coming Soon Posted by Rob Rich on November 28th, 2014 [ | Read more »
Primitive Review
Primitive Review By Jordan Minor on November 28th, 2014 Our Rating: :: FOLK ARTUniversal App - Designed for iPhone and iPad True to its name, Primitive is about as straightforward as runners get.   | Read more »
7 tips to get ahead of the competition i...
7 tips to get ahead of the competition in Dynasty of Dungeons Posted by Simon Reed on November 28th, 2014 [ permalink ] Playcrab has launched their action-packed new dungeon crawler, Dynasty of Dungeons, today. | Read more »
Master of Tea Kung Fu Review
Master of Tea Kung Fu Review By Jordan Minor on November 28th, 2014 Our Rating: :: ONE DROP RULESUniversal App - Designed for iPhone and iPad Master of Tea Kung Fu is a creative and complex caffeinated brawler.   | Read more »
Monster Strike Review
Monster Strike Review By Campbell Bird on November 28th, 2014 Our Rating: :: BILLIARD STRATEGYUniversal App - Designed for iPhone and iPad Collect monsters and battle by flinging them across the battlefield in this strangely... | Read more »
Proun+ Review
Proun+ Review By Jennifer Allen on November 28th, 2014 Our Rating: :: TWITCHY RACINGUniversal App - Designed for iPhone and iPad Twitchy racing aplenty in Proun+, an enjoyably tricky title.   | Read more »
Lucha Amigos (Games)
Lucha Amigos 1.0 Device: iOS Universal Category: Games Price: $1.99, Version: 1.0 (iTunes) Description: Forget Ninja Turtles, and meet Wrestlers Turtles! Crazier, Spicier and…Bouncier! Sling carapaces of 7 Luchadores to knock all... | Read more »
Record of Agarest War Zero (Games)
Record of Agarest War Zero 1.0 Device: iOS Universal Category: Games Price: $7.99, Version: 1.0 (iTunes) Description: HyperDevbox Holiday Turkey Black Friday Special Pricing! To celebrate the opening of the holiday season HyperDevbox... | Read more »

Price Scanner via MacPrices.net

Up To 75% Off Infovole Text Apps Over Black F...
Infovole’s entire range of apps, including the Textkraft family of word processors for iPads and iPhones, is being offered at 50-75% off over the Black Friday and Cyber Monday weekend. The five-day... Read more
Black Friday: Up to $60 off Mac minis, NY tax...
 B&H Photo has new 2014 Mac minis on sale for up to $60 off MSRP as part of their Black Friday sale. Shipping is free, and B&H charges NY sales tax only: - 1.4GHz Mac mini: $449.99 $50 off... Read more
Black Friday: 27-inch 5K iMac for $2299, save...
 B&H Photo continues to offer Black Friday sale prices on the 27″ 3.5GHz 5K iMac, in stock today and on sale for $2299 including free shipping plus NY sales tax only. Their price is $200 off MSRP... Read more
Karalux Announces 24K Gold-Plated iPhone 6
Karalux, a Vietnam-based jewellery firm, has launched a unique 24 karat gold-plated iPhone 6 version with gold-cast monolithic dragon on its back panel. The real 24 karat gold plated enclosure doesn’... Read more
Black Friday: 13-inch 2.6GHz Retina MacBook P...
 B&H Photo has lowered their price for the 13″ 2.6GHz/128GB Retina MacBook Pro to $1159 for Black Friday. That’s $140 off MSRP, and it’s the lowest price for this model (except for Apple’s $1099... Read more
View all the Black Friday sales on our Mac Pr...
We’ve updated our Mac Price Trackers with the latest information on prices, bundles, and availability on systems from Apple’s authorized internet/catalog resellers. View Black Friday sale prices at a... Read more
Black Friday: 11-inch MacBook Air for $779, s...
 Best Buy has lowered their price for the 2014 11″ 1.4GHz/128GB MacBook Air to $779.99 for Black Friday. That’s $120 off MSRP. Choose free shipping or free local store pickup (if available). Sale... Read more
Apple Store Black Friday sale for 2014: $100...
BLACK FRIDAY The Apple Store has posted their Black Friday deals for 2014. Receive a $100 PRODUCT(RED) branded iTunes gift card with the purchase of select Macs, $50 with iPads, and $25 with iPods,... Read more
Black Friday: 15% off iTunes Gift Cards
Staples is offering 15% off $50 and $100 iTunes Gift Cards on their online store as part of their Black Friday sale. Click here for more information. Shipping is free. Best Buy is offering $100... Read more
BEVL Releases Dock Tailored for iPhone 6 and...
Seattle based BEVL has released their first product: an iPhone dock that is divergent in build quality, rock-solid function and visual simplicity to complement the iPhone. BEVL is now accepting... Read more

Jobs Board

*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
Senior Event Manager, *Apple* Retail Market...
…This senior level position is responsible for leading and imagining the Apple Retail Team's global event strategy. Delivering an overarching brand story; in-store, Read more
*Apple* Retail - Multiple Positions (US) - A...
Sales Specialist - Retail Customer Service and Sales Transform Apple Store visitors into loyal Apple customers. When customers enter the store, you're also the Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
*Apple* Solutions Consultant (ASC) - Apple (...
**Job Summary** The ASC is an Apple employee who serves as an Apple brand ambassador and influencer in a Reseller's store. The ASC's role is to grow Apple Read more
All contents are Copyright 1984-2011 by Xplain Corporation. All rights reserved. Theme designed by Icreon.