views:

403

answers:

2

I have a navigation controller based application and I'm running into a strange issue where a few of my view controller pushes are causing crashes upon "popping" the view controller.

I've narrowed it down to the line of code that releases the view controller after pushing it on the navigation controller's stack.

My code looks like this:

SomeViewController *viewController = [[SomeViewController alloc] init];
[self.navigationController pushViewController:viewController animated:YES];
[viewController release];  //offending line

Now this is proper memory management code, but unfortunately I'm getting a "double free sent to instance 0x....." error (in some cases) and my app crashes. This generally happens when I pop said view controller.

I'm looking for suggestions on what to look at. I'm stuck.

Thanks in advance.

Edit: here is the result of the stack trace dump suggested by Louis below.

upon the first release, the retain count is 13 (I guess due to some code deep in the CocoaTouch base classes). Eventually it gets down to this:

2009-08-06 22:33:18.304 My App [26601:20b] ** RELEASE CALLED **
2009-08-06 22:33:18.306 My App [26601:20b] Retain count was : 1
0   My App                              0x000033ec start + 4700
1   CoreFoundation                      0x302042e8 CFRelease + 136
2   CoreFoundation                      0x30227249 CFNumberGetValue + 2937
3   CoreFoundation                      0x30204421 _CFRelease + 241
4   Foundation                          0x30506515 NSPopAutoreleasePool + 341
5   QuartzCore                          0x00b5436e
                                        CA_CGRectUnapplyInverseTransform_ +
                                        19738
6   QuartzCore                          0x00b54109
                                        CA_CGRectUnapplyInverseTransform_ +
                                        19125
7   CoreFoundation                      0x302454a0 CFRunLoopRunSpecific + 3696
8   CoreFoundation                      0x30244628 CFRunLoopRunInMode + 88
9   GraphicsServices                    0x32044c31 GSEventRunModal + 217
10  GraphicsServices                    0x32044cf6 GSEventRun + 115
11  UIKit                               0x309021ee UIApplicationMain + 1157
12  My App                              0x00002258 start + 200
13  My App                              0x000021c6 start + 54
14  ???                                 0x00000001 0x0 + 1
2009-08-06 22:33:18.307 My App [26601:20b] ########### DEALLOC
#
objc[26601]: FREED(id): message retainCount sent to freed

object=0xd09070

If I omit the offending line above (the [viewController release];) then the retain count only makes it to 2 and the instance is never dealloc'ed.

A: 

It is being released somewhere else. If you want to see who is calling it you can just break on release calls to the class. Another option would be to print out the stack trace in release:

#include <execinfo.h>
#include <stdio.h>

- (void) release {
  void* callstack[128];
  int i, frames = backtrace(callstack, 128);
  char** strs = backtrace_symbols(callstack, frames);
  for (i = 0; i < frames; ++i) {
    printf("%s\n", strs[i]);
  }
  free(strs);

  [super release];
}
Louis Gerbarg
I'll try this when I get home...
Ben Scheirman
updated the question with the results of this...
Ben Scheirman
this eventually helped me figure out the problem, which was a double released label elsewhere in the app.
Ben Scheirman