崩溃日志帮助
Posted
技术标签:
【中文标题】崩溃日志帮助【英文标题】:Help with crash log 【发布时间】:2011-08-25 17:24:59 【问题描述】:我的应用在 Lion 从睡眠中醒来时崩溃。 问题似乎与正在寻找天气信息的后台线程有关。 我不确定,但我认为崩溃日志告诉我自动释放池正在弹出不再存在的对象,有人可以帮我确认一下吗?
以下是崩溃日志的相关详细信息:
进程:myApp [14187] 标识符:myApp 版本: ??? (???) 代码类型:X86-64 (Native) 父进程:launchd [224]
日期/时间:2011-08-24 18:58:00.581 -0400 操作系统版本:Mac OS X 10.7.1 (11B26) 报告版本:9
崩溃的线程:7
异常类型:EXC_BAD_ACCESS (SIGSEGV) 异常代码: KERN_INVALID_ADDRESS 在 0x0000000000000010
应用程序特定信息:objc[14187]:垃圾收集是 关闭
线程 7 崩溃:0 libobjc.A.dylib 0x00007fff9321700b(匿名 命名空间)::AutoreleasePoolPage::pop(void*) + 385 1 com.apple.CoreFoundation 0x00007fff961306a5 CFAutoreleasePoolPop + 37 2 com.apple.Foundation 0x00007fff969350d7 -[NSAutoreleasePool 排水] + 154 3 com.piso13.opusDomini 0x00000001000acb91 -[天气 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
这是我的天气内部启动代码:
-(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];
我什至应该打电话给 [pool drain] 吗?
【问题讨论】:
这里看起来没什么问题...你能展示一些generateForecastQuery
或generateQuery
吗?或者你的XmlWrapper
班级?
你从哪里复制了崩溃日志?这一切都被错误包装了。请从您的 ~/Library/Logs 文件夹中的原始崩溃日志文件中复制它并编辑您的问题以包含带有代码格式的文本。
在创建 XMLWrapper
对象后立即释放它们是一个危险信号。你为什么要这样做?
Peter 崩溃日志不在我的电脑中,它是发送给我的。我很抱歉。
【参考方案1】:
创建具有绑定生命周期和显式范围的自动释放池。
在这种情况下,您将自动释放池存储在 ivar(假定)中。
只需将其设置为方法的本地,如下所示:
- (void)internalStart
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
//...
[pool drain], pool = nil;
通常会引入的问题是:
1) 自动释放池是基于堆栈的(池被推送和弹出)。抓住它,你可以很容易地弄乱堆栈顺序。
2) 如果此类在多线程上下文中运行,当您从多个线程推送和弹出池时,您可以轻松地泄漏池或破坏堆栈顺序。
3) 您还可以在多线程上下文中泄漏池
【讨论】:
更简单地说:当这个方法在两个不同的线程上运行时,每个线程都会将自己的自动释放池放入pool
实例变量中——但由于实例变量根据定义是 per -instance,两个线程都将它们的池放在同一个地方。只有一个获胜,然后两个线程都试图耗尽同一个池。这就是崩溃。
Peter 谢谢你,这就是崩溃......你能帮我尽快发布吗?此 xmlWrapper 从 Internet 读取信息并在天气信息准备好时向委托(调用者)发送消息。 xmlWrapper 会在处理时被销毁吗?【参考方案2】:
不幸的是,自动释放池崩溃是最难调试的。从静态分析器开始,它可以找到一些东西。
然后开启NSZombies。
您的XmlWrapper
对象有点奇怪。为什么一创建就立即发布呢?这是NSURLConnection
的包装吗?您仍应持有该对象,以便在该对象被释放时取消它或清除其委托。
确保您对所有 ivars 都使用访问器,而不是直接访问它们。根据我的经验,直接访问 init
和 dealloc
之外的 ivars 是导致此类崩溃的第一大原因。
【讨论】:
从您的 cmets 来看,我想我可能会过早地发布 xmlWrapper。 xmlwrapper 将向委托(当前调用者)发送一条消息,表明信息已准备好读取。在向委托发送完成消息之前,是否可以在其内部处理过程中释放此对象?以上是关于崩溃日志帮助的主要内容,如果未能解决你的问题,请参考以下文章