我正在使用Objective-C编写应用程序,但出现此错误:
MyApp(2121,0xb0185000)malloc:***对象0x1068310的错误:double free
***在malloc_error_break中设置一个断点以进行调试
当我释放NSAutoreleasePool时,就发生了这种情况,但是我无法弄清楚我要两次释放哪个对象。
我如何设置他的断点?
有没有办法知道什么是“对象0x1068310”?
我正在使用Objective-C编写应用程序,但出现此错误:
MyApp(2121,0xb0185000)malloc:***对象0x1068310的错误:double free
***在malloc_error_break中设置一个断点以进行调试
当我释放NSAutoreleasePool时,就发生了这种情况,但是我无法弄清楚我要两次释放哪个对象。
我如何设置他的断点?
有没有办法知道什么是“对象0x1068310”?
Answers:
在调试器中中断时,您将发现对象是什么。只需查找调用堆栈,您就会找到释放它的位置。这将告诉您它是哪个对象。
设置断点的最简单方法是:
- 转到运行- >查看- >断点(ALT- - )CommandB
- 滚动到列表底部并添加符号
malloc_error_break
当一个对象被“双重释放”时,最常见的原因是您(不必要地)释放了一个自动释放的对象,并且在清空包含自动释放池的对象之后,它会被自动释放。
我发现,跟踪额外发行版的最佳方法是对Xcode中受影响的可执行文件使用NSZombieEnabled环境变量。要快速了解如何使用它,请查看此CocoaDev Wiki页面。(除此页面外,Apple还记录了一些在Xcode中调试代码的晦涩难懂却有用的提示,其中一些节省了我的培根数次。我建议在developer.apple.com上查阅本技术说明—链接跳至“可可基金会框架”部分。
编辑:您通常可以在Xcode调试器中跟踪有问题的对象,但是如果您使用Instruments来协助您,通常会容易得多。从Xcode中,选择“运行”→“从性能工具开始”→“对象分配”,您应该能够将有问题的对象追溯到其创建位置。(如果您如上所述启用了僵尸,这将是最好的选择。)注意: Snow Leopard向“工具”添加了“僵尸”工具,也可以从“运行”菜单访问该工具。单单花29美元就值得!;-)
这里还有一个相关的SO问题。
除了奎因·泰勒(Quinn Taylor)的答案,我只想补充一下我的经验。
在我的一个应用程序中,我必须解析数据并将其保存到核心数据对象中,然后再将这些对象显示在视图中。实际上,该应用程序运行良好,并且完全不会崩溃,直到我尝试进行多次来回导航的压力测试,并尝试尽快打开多个视图。该应用程序崩溃并显示以上消息。
我尝试了奎因在他的回答中建议的所有方法,但仍然无法找出真正的原因。
我设置了NSZombieEnabled = YES,并且设置了NSStackLogging = YES,运行了命令shell malloc_history来找出原因,但是还是没有运气。它总是指出我将数据保存到核心数据对象中的位置,实际上,我已经检查了那里超量释放对象的数千次,没有什么奇怪的。
使用各种工具(分配,泄漏等)在Instruments中运行仍然无济于事。启用Guard Malloc仍然一无所获。
最终救助:我尝试返回从Core Data提取对象的视图,并向所有这些对象发送了保留消息,并记录了这些更改。它解决了问题!!!
因此,我发现我没有保留一个,这就是原因。只想分享我的经验,以便为您的应用程序另辟rescue径。
通过按Cmd + Shift + R打开调试器控制台。在那里,输入
break malloc_error_break
在malloc_error_break
函数开始处设置一个断点。
如果要查找位于地址0x1068310的对象,可以在调试器控制台中键入以下内容:
print-object 0x1068310
当然,您必须在对象仍处于活动状态时执行此操作-如果在执行此操作时对象已被释放,则此操作将无效。
po
别名,或等效地使用expr -o
。自最初编写此答案以来,多年来,Xcode使用的调试引擎已从GDB更改为LLDB,并且LLDB具有一组不同的命令。
只是更新使其与Xcode 4相关...
添加一个符号断点。。。
- 在断点导航器的左下角,单击“添加”按钮。
- 选择添加符号断点。
- 在符号字段中输入符号名称。
- 单击完成。
这就是malloc_error_break断点在Xcode的Breakpoints窗口中的样子。需要选中复选框才能使其正常工作。
替代文字http://www.martijnthe.nl/wp-content/uploads/2009/08/Afbeelding-1.png
通常,要查找此类内存和指针问题,您需要针对诸如Valgrind的运行时内存错误检查器运行代码。这应该能够指出您的代码做错了很多事情,除了那些导致代码崩溃的事情。
Valgrind可以在OSX上运行(尽管它说它是“不受支持的,不完整的和有缺陷的”),并且通过一点点黑客就可以使其在iPhone SDK可执行文件上运行。
更好的是,您可以尝试XCode的一部分Instruments。有运行它的教程在这里。