respondsToSelector send to deallocated object

testing picture testing · Aug 28, 2010 · Viewed 9.7k times · Source

I try to find out why my app crashes (RSS Reader) if I send a wrong URL to NSXML Parser. I got an EXC_BAD_ACCESS. So after some Searching I found out that I have to use Zombies. So I added the following arguments to the environment:

CFZombieLevel = 3
NSMallocStaclLogging = YES
NSDeallocateZombies = NO
MallocStackLoggingNoCompact = YES
NSZombieEnabled = YES
NSDebugEnabled = YES
NSAutoreleaseFreedObjectCheckEnabled = YES

I also added malloc_error_break as breakpoint. Then I added some other breakpoints in the GUI and pressed Build and Debug. In the console I get the following message:

2010-08-28 18:41:49.761 RssReader[2850:207] *** -[XMLParser respondsToSelector:]: message sent to deallocated instance 0x59708e0

Sometimes I also get the following message: wait_fences: failed to receive reply: 10004003

If I type in "shell malloc_history 2850 0x59708e0" I get the following:

...
ALLOC 0x5970870-0x59709d7 [size=360]: thread_a0aaa500 |start | main | UIApplicationMain | -[UIApplication _run] | CFRunLoopRunInMode | CFRunLoopRunSpecific | __CFRunLoopRun | __CFRunLoopDoSource1 | __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ | PurpleEventCallback | _UIApplicationHandleEvent | -[UIApplication sendEvent:] | -[UIApplication handleEvent:withNewEvent:] | -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] | -[UIApplication
...
----
FREE  0x5970870-0x59709d7 [size=360]: thread_a0aaa500 |start | main | UIApplicationMain | -[UIApplication _run] | CFRunLoopRunInMode | CFRunLoopRunSpecific | __CFRunLoopRun | __CFRunLoopDoSource1 | __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ | PurpleEventCallback | _UIApplicationHandleEvent | -[UIApplication sendEvent:] | -[UIApplication handleEvent:withNewEvent:] | -[UIApplication
...
ALLOC 0x59708e0-0x597090f [size=48]: thread_a0aaa500 |start | main | UIApplicationMain | -[UIApplication _run] | CFRunLoopRunInMode | CFRunLoopRunSpecific | __CFRunLoopRun | __CFRunLoopDoSource1 | __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ | PurpleEventCallback | _UIApplicationHandleEvent | -[UIApplication sendEvent:] | -[UIApplication handleEvent:withNewEvent:] | -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] | -[UIApplication 
... 
Binary Images:
    0x1000 -     0x6ff3 +RssReader ??? (???) <6EBB16BC-2BCE-CA3E-C76E-F0B078995E2D> /Users/svp/Library/Application Support/iPhone Simulator/4.0.1/Applications/AF4CE7CA-88B6-44D4-92A1-F634DE7B9072/RssReader.app/RssReader
    0xe000 -   0x1cfff3 +Foundation 751.32.0 (compatibility 300.0.0) <18F9E1F7-27C6-2B64-5B9D-BAD16EE5227A>
...

What does this mean? How do I know which object 0x59708e0 is? I can't find the code which causes my app to crash. The only thing I know is that it should be a respondsToSelector message. I added a breakpoint to all my respondsToSelector messages. They get hitted but the app crashes not at that point. I also tried to comment them out except for one and also gets the app crashing. The one which was not commented out, wasn't hit. Where do I have a memory leak?

The next confusing thing is that NSXML Parser continue its' work, despite the parseErrorOccurred delegate is called. After two times an error is thrown, the app crashes.

Why is Zombies in the Run with Peformance Tool disabled?

Edit:

Now I used this instruction (not able to post. sorry. spam prevention) I got this working. What is the meaning of this?

@Graham: In my parser class I instantiate NSXMLParser:

- (void)connectionDidFinishLoading:(NSURLConnection *)connection {  
        ... 
    NSXMLParser *rssParser = [[NSXMLParser alloc] initWithData:responseData];  
    [rssParser setDelegate:self];
        ...
    [rssParser parse];
    //[rssParser release];
}

During I searched the error, I commented out the release method. Currently rssParser never get's released in the parser class.

In my RootViewController class I instantiate my parser:

- (void)loadData {
    if (newsItems == nil) {
        [activityIndicator startAnimating];  

        XMLParser *rssParser = [[XMLParser alloc] init];  
        [rssParser parseRssFeed:@"http://feeds2.feedburner.com/TheMdnShowtest" withDelegate:self];  

        [rssParser release];
        rssParser = nil;

    } else {  
        [self.tableView reloadData];  
    }  
}

If I don't release it here, it doesn't crash. But for each alloc I have to do a release? Or should I autorelease NSXMLParser in connectionDidFinishLoading?

Answer

rano picture rano · Aug 28, 2010

Zombie is disabled as you use it with Memory Leaks since all Zombies would be signaled as leaks. To run the Zombie tool you can go to the Instrument menu and do File>New and chose the Zombie tool alone, doing so the program will stop if a zombie has received a message and you'll be given a link in a small pop up to that zombie object and its history