2012-02-06 38 views
0

我的Mac应用程序在运行循环中碰撞exc_bad_access。 所以我启用NSZombies,现在我没有看到预期的错误(因为对象没有解除分配)。已启用NSZombies,调试信息

但是,我没有找到任何有用的NSZombie登录控制台。 有没有办法找出问题?

回答

3

这很具有挑战性。 Cocoa中这个错误的最常见原因是直接访问你的ivars而不是使用访问器。访问器使绝大多数内存崩溃消失。

这就是说,它们不是导致内存错误的唯一原因。您可能正在以其他方式访问内存。 NSZombie做了一件特别的事情:当您释放一个对象时,NSZombie说“实际上不会释放该对象。”相反,它会将对象转换为僵尸对象,如果您发送消息则会打印一个错误。但是,这只有在崩溃是由于将消息发送到解除分配的实例时才有用。这可能是很多其他的事情。

您应该先从崩溃堆栈本身开始。查看堆栈并查看它可能是什么类型的对象,或者可能调用它的对象。

阅读TN2124,特别是关于BSD内存分配器的部分,以及内存使用性能指南的Enabling the Malloc Debugging Features部分。有比您可以使用的NSZombie更低级别的工具。 MallocScribble通常是最有用的。它用0x55覆盖释放的内存,以便更快地崩溃,并更容易检测调试器中的释放内存。 MallocPreScribble对于查找未初始化的内存非常有用,但这只有在您执行原始malloc调用时才有用。 ObjC对象总是被预先初始化。

当然,你必须戴上你的侦探帽子。你的计划哪些部分最可疑?你正在做多线程工作(如果你没有正确锁定,会导致内存崩溃)。

如果它很容易重现,那么你会弄清楚。如果它只是偶尔发生,那么......我有时会在很多个月内找到像这样的错误。有时候这很难。

+0

应用程序与NSZombie运行得很好。正如你所说,NSZombie实际上并没有释放对象。 想知道如果有消失来检测任何尝试引用该解除分配的对象。 – coder000001 2012-02-06 22:53:34

+0

不准确,但MallocScribble将有所帮助。当你使用它时,不要忘记MallocStackLogging。 – 2012-02-06 23:03:02

+0

谢谢,它真的帮助。我缩小了它http://stackoverflow.com/questions/9168936/hidmanager-wierd-cfrunloop-termination – coder000001 2012-02-06 23:40:49

0

您需要使用内存分析器。只需使用Profile选项并选择泄漏。

+0

是的,我触发了分析器。我没有发现任何奇怪或任何僵尸消息 – coder000001 2012-02-06 22:51:10