如何找到导致malloc“双重释放”错误的原因?


80

我正在使用Objective-C编写应用程序,但出现此错误:

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

当我释放NSAutoreleasePool时,就发生了这种情况,但是我无法弄清楚我要两次释放哪个对象。

我如何设置他的断点?

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


3
您可能也想用iPhone标记此帖子,以吸引更多人
Benny Wong

4
删除了“ iphone”标签,转而使用其他更相关的标签。
奎因·泰勒,

3
我无法想象为什么这个iPhone问题会丢失iPhone标签。与“ autorelease”之类的其他其他标签相比,使用“ iPhone”的人一定更多。如果要查找“自动发布”,则进行搜索,而不必遵循标签。所以我把“iPhone”回来了。
Nosredna

6
我删除“ iphone”标签的原因是,与该问题无关的问题仅适用于iPhone。唯一的链接是它发生在iPhone应用程序中,但是在任何C或Objective-C应用程序中都可能发生完全相同的错误。我不希望跟随iPhone的人们对此产生兴趣,而是会搜索“双重免费”或“ malloc_error_break”之类的东西,并且如果他们抛弃“ iPhone”,它仍然会出现。让我们不要为标签争论不休,而要考虑的是,回答问题的人可能知道问题最明显的地方。
奎因·泰勒,

3
这个问题至少是针对可可的。如果iPhone标签冒犯了,可可标签又如何呢?明显的意图适用于XCode中关于Cocoa的Objective-C。Windows,Linux或XCode上下文之外的不是Objective-C。
09年

Answers:


38

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

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

  1. 转到运行- >查看- >断点(ALT- - )CommandB
  2. 滚动到列表底部并添加符号 malloc_error_break

1
我试过了,但是得到了:无法解析malloc_error_break ....这是什么意思?
贡苏

3
自动释放双重免费无帮助。他需要僵尸
Rog

58
@gonso —很好奇,如果这对您不起作用,您为什么接受它作为答案?
奎因·泰勒

8
在Xcode 4.3.2中,可以在“视图”→“导航器”→“显示断点导航器”或⌘6(Cmd-6)
Andreas Ley

46

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

我发现,跟踪额外发行版的最佳方法是对Xcode中受影响的可执行文件使用NSZombieEnabled环境变量。要快速了解如何使用它,请查看此CocoaDev Wiki页面。(除此页面外,Apple还记录了一些在Xcode中调试代码的晦涩难懂却有用的提示,其中一些节省了我的培根数次。我建议在developer.apple.com上查阅本技术说明—链接跳至“可可基金会框架”部分。

编辑:您通常可以在Xcode调试器中跟踪有问题的对象,但是如果您使用Instruments来协助您,通常会容易得多。从Xcode中,选择“运行”→“从性能工具开始”→“对象分配”,您应该能够将有问题的对象追溯到其创建位置。(如果您如上所述启用了僵尸,这将是最好的选择。)注意: Snow Leopard向“工具”添加了“僵尸”工具,也可以从“运行”菜单访问该工具。单单花29美元就值得!;-)

这里还有一个相关的SO问题


1
在答案中链接的CocoaDev Wiki页面已死:(
Devarshi


13

除了奎因·泰勒(Quinn Taylor)的答案,我只想补充一下我的经验。

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

我尝试了奎因在他的回答中建议的所有方法,但仍然无法找出真正的原因。

我设置了NSZombieEnabled = YES,并且设置了NSStackLogging = YES,运行了命令shell malloc_history来找出原因,但是还是没有运气。它总是指出我将数据保存到核心数据对象中的位置,实际上,我已经检查了那里超量释放对象的数千次,没有什么奇怪的。

使用各种工具(分配,泄漏等)在Instruments中运行仍然无济于事。启用Guard Malloc仍然一无所获。

最终救助:我尝试返回从Core Data提取对象的视图,并向所有这些对象发送了保留消息,并记录了这些更改。它解决了问题!!!

因此,我发现我没有保留一个,这就是原因。只想分享我的经验,以便为您的应用程序另辟rescue径。


9

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

break malloc_error_break

malloc_error_break函数开始处设置一个断点。

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

print-object 0x1068310

当然,您必须在对象仍处于活动状态时执行此操作-如果在执行此操作时对象已被释放,则此操作将无效。


这是自动发行,他需要僵尸。
罗格2009年

1
最后,我所做的是在AutoreleasePoll之外调用“可疑”方法。有趣的想法是我仍然可以得到警告,但是没有遇到任何断点。我只是注释掉了块,直到找到该行。我正在自动释放使用stringWithFormat创建的字符串(无分配或复制)。谢谢大家的提示!贡索
贡索2009年

对于这种特定类型的错误,中断malloc_error_break从未帮助发现问题-它始终需要启用僵尸程序。
奎因·泰勒,

看到这里说明在Xcode中4设置一个断点malloc_error_break:stackoverflow.com/questions/6969407/...
benvolioT

1
@Zammbi:尝试使用po别名,或等效地使用expr -o。自最初编写此答案以来,多年来,Xcode使用的调试引擎已从GDB更改为LLDB,并且LLDB具有一组不同的命令。
亚当·罗森菲尔德

4

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

(gdb) call (void)_CFAutoreleasePoolPrintPools()

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

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


4

在Xcode 4中添加符号断点

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

Xcode 4用户指南中

添加一个符号断点。。。

  1. 在断点导航器的左下角,单击“添加”按钮。
  2. 选择添加符号断点。
  3. 在符号字段中输入符号名称。
  4. 单击完成。


2

检查您的类并在dealloc方法下查看。确保您在乎打电话[super dealloc].

我遇到了完全相同的问题,发现我正在打电话给我[self dealloc]。只是不注意。


2

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

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

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

GIF表达


1

这通常是由某些检查人员引起的,例如safari或safari Preview。请参阅发布发布问题

删除“自动显示Web ....”的选择,将消除此问题。

请注意,仅关闭野生动物园或野生动物园预览不会解决此问题。而且您必须取消选择safari和safari预览。

如果这样做不行,请参考此答案发布以对其进行调试。

取消选择会在Safari浏览器预览中自动检查


0

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

建议不要创建对象,autorelease因为内存是iPhone上的商品。苹果建议显式调用release


0

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

Valgrind可以在OSX上运行(尽管它说它是“不受支持的,不完整的和有缺陷的”),并且通过一点点黑客就可以使其在iPhone SDK可执行文件上运行

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


1
仪器是必经之路;使用对象分配工具并打开僵尸。(或仅使用“僵尸”模板)。Valgrind是万不得已的解决方案。它的运行速度非常慢,而且通常根本无法正常工作。
bbum

0

如果malloc_error_break没有帮助...

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

需要雪豹,但多么救命!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.