81

我正在用 Objective-C 编写一个应用程序,我收到了这个错误:

MyApp(2121,0xb0185000) malloc: *** 对象 0x1068310 错误: double free
*** 在 malloc_error_break 中设置断点进行调试

当我释放一个 NSAutoreleasePool 并且我无法弄清楚我要释放两次的对象时,就会发生这种情况。

我如何设置他的断点?

有没有办法知道这个“对象0x1068310”是什么?

4

13 回答 13

47

当一个对象被“双重释放”时,最常见的原因是你(不必要地)释放了一个自动释放的对象,然后当包含的自动释放池被清空时它被自动释放。

我发现追踪额外版本的最佳方法是在 Xcode 中为受影响的可执行文件使用NSZombieEnabled环境变量。要快速了解如何使用它,请查看这个 CocoaDev wiki 页面。(除了这个页面之外,Apple 还记录了一些在 Xcode 中调试代码的非常晦涩但有用的技巧,其中一些已经多次保存了我的培根。我建议在 developer.apple.com 上查看此技术说明— 链接跳转到 Cocoa 的 Foundation 框架部分)。

编辑:您通常可以在 Xcode 调试器中跟踪有问题的对象,但如果您使用 Instruments 来帮助您,这通常会容易得多。在 Xcode 中,选择Run → Start With Performance Tool → Object Allocations,您应该能够将有问题的对象追溯到它的创建位置。(如果您如上所述启用了僵尸,这将最有效。)注意: Snow Leopard 向 Instruments 添加了一个 Zombies 工具,也可以从 Run 菜单访问。光是 29 美元就值了!;-)

还有一个相关的 SO question here

于 2009-06-11T03:33:58.873 回答
38

当您中断调试器时,您会发现对象是什么。只需查找调用堆栈,您就会找到释放它的位置。这会告诉你它是哪个对象。

设置断点的最简单方法是:

  1. 转到运行 -> 显示 -> 断点 ( ALT- Command- B)
  2. 滚动到列表底部并添加符号malloc_error_break
于 2009-06-09T18:06:33.787 回答
13

除了Quinn Taylor的回答,我只想添加我的经验。

在我的一个应用程序中,我必须将数据解析并保存到核心数据对象中,然后让这些对象显示在视图上。实际上,该应用程序运行良好并且根本不会崩溃,直到我尝试进行多次来回导航的压力测试,并尝试尽可能快地打开多个视图。应用程序因上述消息而崩溃。

我已经尝试了 Quinn 在他的回答中建议的所有方法,但仍然无法找出确切原因。

我设置了 NSZombieEnabled=YES 和 NSStackLogging=YES,运行命令 shell malloc_history 找出原因,但仍然没有运气。它总是指出我将数据保存到核心数据对象的位置,事实上,我已经检查了数千次过度释放的对象,没有什么奇怪的。

使用各种工具(分配、泄漏等)在仪器中运行仍然没有帮助。启用 Guard Malloc 仍然一无所获。

最后的救援:我试图回到从 Core Data 中获取对象并向所有这些对象发送保留消息的视图,并记下这些更改。解决了问题!!!

所以,我发现我没有保留一个,这正是原因。只是想分享我的经验,以便您的应用程序有另一个救援。

于 2010-11-03T13:32:32.793 回答
9

按 Cmd+Shift+R 打开调试器控制台。在那里,输入

break malloc_error_break

malloc_error_break在函数的开头设置断点。

如果要找出地址 0x1068310 处的对象,可以在调试器控制台中键入以下内容:

print-object 0x1068310

当然,你必须在对象还活着的时候这样做——如果在你这样做的时候对象已经被释放了,那么这将不起作用。

于 2009-06-11T03:51:59.247 回答
4

对我来说,这个问题已经解决了

(gdb) call (void)_CFAutoreleasePoolPrintPools()

就在坠机之后。堆栈顶部的地址是罪魁祸首的地址。扔进去retain,瞧。

日志消息中给出的地址没有让我到任何地方。它从未出现在任何各种乐器中。显然是指向一些已经被释放的内部数据的指针。

于 2011-07-09T17:59:05.180 回答
4

在 Xcode 4 中添加符号断点

只是一个更新,使其与 Xcode 4 相关......

来自Xcode 4 用户指南

添加一个符号断点。. .

  1. 在断点导航器的左下角,单击添加按钮。
  2. 选择添加符号断点。
  3. 在符号字段中输入符号名称。
  4. 单击完成。
于 2011-12-17T19:54:26.423 回答
4

请找到以下步骤,了解如何找到免费的对象并使应用程序崩溃。

1) 单击“断点导航器”。
2) 然后点击下方的“ + ”按钮。
3)从列表中添加“符号断点... ”。
4)在“ Symbol ”选项上添加“ malloc_error_break ”关键字。

或者您也可以参考下面的 GIF 演示文稿。

GIF 表示

于 2017-05-25T13:31:28.050 回答
3

这就是 Xcode 断点窗口中 malloc_error_break 断点的样子。需要选中复选框以使其工作。

替代文字 http://www.martijnthe.nl/wp-content/uploads/2009/08/Afbeelding-1.png

于 2009-08-05T10:51:57.963 回答
2

检查您的类并查看 dealloc 方法。确保你关心打电话[super dealloc].

我遇到了同样的问题,发现我正在打电话[self dealloc]。就是不注意。

于 2010-11-11T17:27:36.507 回答
0

在 Xcode 中,单击行号左侧以设置断点。然后您可以通过执行“构建和调试”来启动它。

建议不要有您创建的对象,autorelease因为内存是 iPhone 上的商品。Apple 建议明确调用release.

于 2009-06-09T18:00:37.790 回答
0

通常,要查找这些类型的内存和指针问题,您需要针对Valgrind等运行时内存错误检查器运行代码。这应该能够指出你的代码做错的很多事情,除了那些导致它崩溃的事情。

Valgrind可以在 OSX 上工作(尽管它说它“不受支持、不完整和有问题”),并且通过一点黑客攻击,有人让它在iPhone SDK 可执行文件上工作。

更好的是你可以试试 Instruments,它是 XCode 的一部分。这里有一个运行它的教程。

于 2009-06-29T18:29:28.483 回答
0

如果malloc_error_break没有帮助...

解决此错误的最佳方法是在打开的情况下运行仪器。NSZombies当 Zombie 收到消息时,Instruments 会标记您,您可以直接追溯到代码行。

雪豹需要,但这是一个救星!

于 2011-05-18T19:07:05.983 回答
0

这通常是由某些检查器引起的,例如 safari 或 safari preview。请参阅帖子帖子问题

删除 AutoMatically Show Web .... 的选择,将消除此问题。

请注意,仅关闭 safari 或 safari 预览不会消除此问题。而且您必须取消选择 safari 和 safari 预览。

如果这样做不行,请参考此答案帖子进行调试。

取消选择自动检查 Safari 预览

于 2017-05-10T07:12:10.400 回答