开发者

Help with crash log

My app is crashing on Lion when it awakes from sleep. The problem seems to be with a background thread that is looking for weather info. I'm not sure but I think the crash log is telling me that the autorelease pool is popping objects that are no longer there, can someone help me confirm this?

Here is the relevant details for the Crash log:

Process:开发者_StackOverflow myApp [14187] Identifier: myApp Version:

??? (???) Code Type: X86-64 (Native) Parent Process: launchd [224]

Date/Time: 2011-08-24 18:58:00.581 -0400 OS Version: Mac OS X 10.7.1 (11B26) Report Version: 9

Crashed Thread: 7

Exception Type: EXC_BAD_ACCESS (SIGSEGV) Exception Codes: KERN_INVALID_ADDRESS at 0x0000000000000010

Application Specific Information: objc[14187]: garbage collection is OFF

Thread 7 Crashed: 0 libobjc.A.dylib

0x00007fff9321700b (anonymous namespace)::AutoreleasePoolPage::pop(void*) + 385 1

com.apple.CoreFoundation 0x00007fff961306a5 CFAutoreleasePoolPop + 37 2 com.apple.Foundation

0x00007fff969350d7 -[NSAutoreleasePool drain] + 154 3

com.piso13.opusDomini 0x00000001000acb91 -[Weather internalStart] + 417 4 com.apple.Foundation

0x00007fff9698b1ea -[NSThread main] + 68 5 com.apple.Foundation

0x00007fff9698b162 NSThread_main + 1575 6 libsystem_c.dylib

0x00007fff90b068bf _pthread_start + 335 7 libsystem_c.dylib

0x00007fff90b09b75 thread_start + 13

Here is my code for Weather Internal Start:

-(void)internalStart{
    pool = [[NSAutoreleasePool alloc] init];

    forecast = FALSE;
    liveweather = FALSE;

    NSString *query = [self generateQuery];
    if (query == nil) {
        [pool drain];
        return;
    }


    XmlWrapper * xmlWrapper = [[XmlWrapper alloc] initWithQuery:query delegate:self name:@"liveweather"];
    [xmlWrapper release];

    query = [self generateForecastQuery];
    xmlWrapper = [[XmlWrapper alloc] initWithQuery:query delegate:self name:@"forecast"];
    [xmlWrapper release];

    [pool drain];

}

Should I even be calling [pool drain] ?


create your autorelease pools with bound lifetimes and explicit scopes.

in this case, you store your autorelease pool in an ivar (presumed).

just make it local to the method, like so:

- (void)internalStart
{
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
    //...
    [pool drain], pool = nil;
}

the problems that are typically introduced are:

1) autorelease pools are stack based (pools are pushed and popped). by holding onto it, you can easily mess up the stack order.

2) if this class operates in a multithreaded context, you can easily leak pools or destroy the stack order when you push and pop pools from multiple threads.

3) you could also leak pools in multithreaded contexts


Unfortunately, autoreleasepool crashes are some of the hardest to debug. Start with the static analyzer, which can find some things.

Then turn on NSZombies.

Your XmlWrapper object is a bit strange. Why do you immediately release it as soon as you create it? Is this a wrapper around NSURLConnection? You should still hold onto the object so that you can cancel it or clear its delegate when this object is released.

Make sure you're using accessors for all your ivars rather than accessing them directly. Direct access to ivars outside of init and dealloc is the #1 cause of these kinds of crashes in my experience.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜