【问题标题】:How to find the cause of a malloc "double free" error?如何找到 malloc “双重释放”错误的原因?
【发布时间】:2010-11-01 13:22:58
【问题描述】:

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

MyApp(2121,0xb0185000) malloc: *** 对象 0x1068310 的错误: 双重释放
*** 在 malloc_error_break 中设置断点进行调试

当我释放 NSAutoreleasePool 时会发生这种情况,但我无法确定我要释放两次的对象。

如何设置他的断点?

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

【问题讨论】:

  • 你可能也想用 iPhone 标记这篇文章以吸引更多人
  • 删除了“iphone”标签以支持其他更相关的标签。
  • 我无法想象为什么这个 iPhone 问题会缺少 iPhone 标签。关注“iPhone”的人数肯定比关注“autorelease”等其他标签的人数要多。如果你想找到“autorelease”,你搜索它,你不跟随标签。所以我把“iPhone”放回去了。
  • 我删除“iphone”标签的原因是因为这个问题没有什么是特定于 iPhone 的。唯一的链接是它发生在 iPhone 应用程序中,但完全相同的错误可能发生在任何 C 或 Objective-C 应用程序中。我不认为关注 iPhone 的人会随便对此感兴趣——相反,会是那些搜索诸如“double free”或“malloc_error_break”之类的东西的人,如果他们扔进“iPhone”,它仍然会出现.让我们不要为标签争吵,但考虑一下,也许回答的人可能知道问题的最佳归属。
  • 这个问题至少是 Cocoa 特有的。如果 iPhone 标签有问题,那么可可标签呢?明显的意图适用于 XCode 中 Cocoa 上的 Objective-C。不是 Windows、Linux 或 XCode 上下文之外的 Objective-C。

标签: iphone objective-c memory-management malloc autorelease


【解决方案1】:

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

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

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

还有一个related SO question here

【讨论】:

【解决方案2】:

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

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

  1. 转到运行 -> 显示 -> 断点(ALT-Command-B
  2. 滚动到列表底部并添加符号malloc_error_break

【讨论】:

  • 我试过了,但我得到:无法破解 malloc_error_break.... 这是什么意思?
  • 自动释放双倍免费没有帮助。他需要僵尸
  • @gonso — 只是好奇,如果这对你不起作用,你为什么接受它作为答案?
  • 在 Xcode 4.3.2 中,断点可以在 View → Navigator → Show Breakpoints Navigator 或 ⌘6 (Cmd-6) 中找到
【解决方案3】:

除了奎因·泰勒的回答,我只想添加我的经验。

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

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

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

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

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

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

【讨论】:

    【解决方案4】:

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

    break malloc_error_break
    

    malloc_error_break函数的开头设置断点。

    如果你想知道什么对象位于地址 0x1068310,你可以在调试器控制台中输入以下内容:

    print-object 0x1068310
    

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

    【讨论】:

    • 这是自动释放,他需要僵尸。
    • 最后我所做的是在 AutoreleasePoll 之外调用“可疑”方法。有趣的是,我仍然收到警告,但没有击中断点。我只是注释掉了块,直到找到该行。我正在自动释放使用 stringWithFormat 创建的字符串(没有分配或复制)。谢谢大家的提示!贡索
    • 对于这种特殊类型的错误,打破 malloc_error_break 从来没有帮助找到问题 - 它总是需要启用僵尸。
    • 有关在 XCode 4 中为 malloc_error_break 设置断点的说明,请参见此处:stackoverflow.com/questions/6969407/…
    • @Zammbi:尝试使用po 别名,或等效的expr -o。自最初编写此答案以来的几年中,Xcode 使用的调试引擎已从 GDB 更改为 LLDB,并且 LLDB 具有不同的命令集。
    【解决方案5】:

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

    (gdb) call (void)_CFAutoreleasePoolPrintPools()
    

    就在崩溃之后。堆栈顶部的地址是罪魁祸首的地址。输入retain,瞧。

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

    【讨论】:

      【解决方案6】:

      在 Xcode 4 中添加符号断点

      只是为了使它与 Xcode 4 相关的更新...

      来自Xcode 4 User Guide

      添加一个符号断点。 . .

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

      【讨论】:

        【解决方案7】:

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

        1) 点击“Breakpoint navigator”。
        2) 然后点击 下方的“+”按钮。
        3) 添加“Symbolic” 断点...”从列表中。
        4) 添加 “Symbol”选项中的“ma​​lloc_error_break”关键字。

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

        【讨论】:

          【解决方案8】:

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

          alt text http://www.martijnthe.nl/wp-content/uploads/2009/08/Afbeelding-1.png

          【讨论】:

            【解决方案9】:

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

            我遇到了同样的问题,发现我打电话给[self dealloc]。只是没注意。

            【讨论】:

              【解决方案10】:

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

              建议不要将您创建的对象设为autorelease,因为内存在 iPhone 上是一种商品。 Apple 建议明确调用release

              【讨论】:

                【解决方案11】:

                要找到这些一般的内存和指针问题,您需要针对运行时内存错误检查器(例如 Valgrind)运行代码。这应该能够指出你的代码做错的很多事情,除了那些导致它崩溃的事情。

                Valgrind can work on OSX(尽管它说它“不受支持、不完整且有问题”),并且通过一点黑客攻击,有人让它在 iPhone SDK executables 上工作。

                你还可以试试 Instruments,它是 XCode 的一部分。有一个运行它的教程here

                【讨论】:

                • 仪器是要走的路;使用对象分配工具并打开僵尸。 (或者只使用 Zombies 模板)。 Valgrind 是最后的解决方案。它非常慢,而且通常根本不起作用。
                【解决方案12】:

                如果malloc_error_break 没有帮助...

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

                需要雪豹,但真是救命稻草!

                【讨论】:

                  【解决方案13】:

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

                  去掉 AutoMatically Show Web .... 的选择,就可以解决这个问题了。

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

                  如果不行,请参考此answerpost进行调试。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 2013-05-10
                    • 1970-01-01
                    • 2014-11-10
                    • 2017-02-26
                    • 1970-01-01
                    • 2021-09-02
                    • 2017-03-07
                    相关资源
                    最近更新 更多