我正在收到崩溃报告(通过优秀的Hockey),表明我在dispatch_sync
块中调用的某些代码中存在内存问题(或者至少我是这样的)解释下面的崩溃报告片段)。我根本无法在我的测试设备上重新创建此崩溃(因此像NSZombieEnabled
这样的策略对我没有帮助)。我很乐意进行代码更改,使崩溃报告更具信息性(并最终解决潜在问题),我只是不知道从哪里开始。有什么想法吗?
Exception Type: SIGSEGV
Exception Codes: SEGV_ACCERR at 0xb000000c
Crashed Thread: 7
...
Thread 7 Crashed:
0 libobjc.A.dylib 0x3979bb66 _objc_msgSend + 6
1 libdispatch.dylib 0x39c898fb _dispatch_barrier_sync_f_invoke + 27
2 App 0x00260f23 __48-[Foo displayLinkCallback]_block_invoke + 147
3 libdispatch.dylib 0x39c85103 _dispatch_call_block_and_release + 11
4 libdispatch.dylib 0x39c894bf _dispatch_async_redirect_invoke + 111
5 libdispatch.dylib 0x39c8a7e5 _dispatch_root_queue_drain + 225
6 libdispatch.dylib 0x39c8a9d1 _dispatch_worker_thread2 + 57
7 libsystem_pthread.dylib 0x39db4dff __pthread_wqthread + 299
dispatch_sync
提供了一个静态串行队列。 _objc_msgSend
是否可能表示引用此队列的问题而不是块内的某些问题?
为了预防显而易见的事实,我没有看到这些崩溃报告中出现死锁的迹象。
更新(2013年10月8日)
按要求添加代码(方法和变量名称已更改,但仍接近原始名称)。我怀疑问题是在复制foo
的某个地方。我希望这个问题会产生调试错误的状态。如果“逐行检查”是调试_objc_msgSend
块内dispatch_sync
崩溃的最佳策略,那么它有点难过,但我会在此时获得任何帮助。
另外,我应该指出,我正在调查的崩溃只发生在单核设备上并间歇地发生在那里。
- (void) displayLinkCallback
{
dispatch_async(_frameDispatchQueue, ^{
if ([_lock tryLock])
{
dispatch_sync(_renderQueueSerial, ^{
NSObject *fooCopy = nil;
BOOL bar = NO;
// prevents deallocation during subsequent copy
// _foo is set and/or its child objects changed
// many times per second by other threads)
NSObject *foo = _foo;
// copy foo
fooCopy = [foo copy];
bar = [self needsBarGivenFoo:fooCopy];
if (bar)
{
_lastFoo = foo;
[self goFoo:fooCopy];
}
else
{
[self noFoo:fooCopy];
}
});
[_lock unlock];
}
});
}
答案 0 :(得分:1)
我建议您开始对源文件中的引用进行分析。这个符号化的崩溃日志表明您的崩溃源于displayLinkCallback
类Foo
方法中的某些内容。你应该在那里开始调查。
它告诉你有分段违规。但是如果没有看到该方法的源代码,很难进一步诊断。