帮我诊断这个崩溃

时间:2011-05-01 06:37:02

标签: objective-c cocoa macos memory-management crash

我的应用程序的很多用户正在发送此崩溃,但我无法重复它..所以我正在寻找有关如何排除故障的提示,这是崩溃日志的相关部分:

Exception Type:  EXC_BAD_INSTRUCTION (SIGILL)
Exception Codes: 0x0000000000000001, 0x0000000000000000
Crashed Thread:  0  Dispatch queue: com.apple.main-thread

Application Specific Information:
objc[1535]: FREED(id): message retain sent to freed object=0x640ad0

Thread 0 Crashed:  Dispatch queue: com.apple.main-thread
0   libobjc.A.dylib                     0x9116f4b4 _objc_error + 116
1   libobjc.A.dylib                     0x9116f4ea __objc_error + 52
2   libobjc.A.dylib                     0x9116d7dc _freedHandler + 58
3   ...my_company.my_app      0x00045635 -[MyObject mySelector] + 1494
4   com.apple.Foundation                0x90be18d4 __NSFireTimer + 141
5   com.apple.CoreFoundation            0x93a38adb __CFRunLoopRun + 8059
6   com.apple.CoreFoundation            0x93a36464 CFRunLoopRunSpecific + 452
7   com.apple.CoreFoundation            0x93a36291 CFRunLoopRunInMode + 97
8   com.apple.HIToolbox                 0x92982e04 RunCurrentEventLoopInMode + 392
9   com.apple.HIToolbox                 0x92982bb9 ReceiveNextEventCommon + 354
10  com.apple.HIToolbox                 0x92982a3e BlockUntilNextEventMatchingListInMode     + 81
11  com.apple.AppKit                    0x9576e78d _DPSNextEvent + 847
12  com.apple.AppKit                    0x9576dfce -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 156
13  com.apple.AppKit                    0x95730247 -[NSApplication run] + 821
14  com.apple.AppKit                    0x957282d9 NSApplicationMain + 574
15  ...my_company.my_app      0x00002042 start + 54

所以,从这一行:

3   ...my_company.my_app      0x00045635 -[MyObject mySelector] + 1494

我可以推断,在mySelector中,一条消息被发送到一个已经被释放的对象,但是我已经查看了代码而我看不到它,并且有太多其他依赖项在这里发布代码。

所以我的问题是:

  1. 每行末尾的数字表示,在上面的例子中是1494。
  2. 在前一行中有一个对__NSFireTimer的引用 - 这是否表明我的代码中的NSTimer正在调用mySelector?
  3. 我尝试在启用Zombies的情况下运行我的应用程序,除了在mySelector中为每个对象检查我的代码!= nil,如果我不能重复崩溃,还能做什么?
  4. 对此的任何帮助将不胜感激!

2 个答案:

答案 0 :(得分:0)

使用仪器观看分配。我发现它很有帮助。

答案 1 :(得分:0)

我相信每行末尾的数字表示在回溯中该点处函数内的代码字节的偏移量。调试器将使用此信息将代码偏移映射到实际的源代码行(它需要应用程序中的调试信息才能执行此操作)。在您的情况下,信息不是特别有用。

对NSFireTimer的引用意味着你的主线程的运行循环已经安排了一个计时器,它已经触发了调用[myObject mySelector]。我认为从堆栈跟踪中我们可以假设定时器直接调用了“myObject”,因为没有其他中间堆栈帧。

我的猜测是该对象已被释放,但它是主线程中预定计时器的目标,您忘记删除它。

首先如何释放对象取决于您的应用程序的编译方式。它是使用垃圾收集,还是依赖于保留/释放内存管理?

如果你没有使用垃圾收集,那么你可能错过了某个地方的“保留”。也许你的对象已被自动释放,并且当你没想到它时,runloop已经清理了它?

如果您可以识别所涉及的计时器,您可能需要考虑在类的dealloc或finalize方法中禁用计时器。您还可以在那里添加一些日志记录,以便在释放对象时向您显示。