【问题标题】:iPhone OS memory problem - how to debug?iPhone OS 内存问题 - 如何调试?
【发布时间】:2009-11-08 11:47:37
【问题描述】:

我的 iPhone 应用程序中有一个非常奇怪的问题,我认为这与内存损坏有关:

在某一时刻,我需要对数组进行排序,我使用 -[sortArrayUsingFunction] 进行排序。

结果是不正确的,除非我在方法调用之前使用void *test = malloc(2 * sizeof( int )) 之类的东西分配一些内存,或者在排序函数中调用NSLog()(从不调用)。

换句话说:排序只有在我稍微增加调用排序函数之前使用的内存时才有效。我认为这是因为在某些时候,内存会损坏。

你如何调试这样的东西?

【问题讨论】:

  • 我想你使用 NSMutableArray sortUsingFunction:context:?您应该发布排序功能;
  • 如果您不了解我的应用程序的(太复杂的)上下文,发布排序功能将无济于事。我也不认为问题出在排序功能上,因为那样它总是会失败。

标签: iphone objective-c memory corruption


【解决方案1】:

听起来您的某些代码正在使用已发布的对象。 Apple 伟大的Mac OS X Debugging Magic 技术说明中提供了很多调试此类错误的帮助,尤其是foundation 部分。

对于您的情况,我会禁用自动释放池(设置环境变量 NSEnableAutoreleasePool=NO)或使用僵尸功能 (NSZombieEnabled=YES) 来查找向已释放对象发送消息的位置。

【讨论】:

  • 当我设置 NSEnableAutoreleasePool=NO 时问题似乎消失了。但是在设置 NSZombieEnabled 时我没有收到任何消息,如果我没有将 NSEnableAutoreleasePool 设置为 NO,而是在 main.m 中将池设置为 nil(应该是等效的),问题仍然存在......一切都还在很奇怪,但自动释放可能是问题。
  • 好的,现在你知道过度释放可能是问题所在。首先尝试静态分析器(clang)。然后,如果您没有发现问题,请开始查看可疑对象并保留它们。如果问题随后消失,您就知道哪个对象在其时间之前被释放了。
  • 顺便说一句:当然你必须在启用僵尸检测时启用自动释放池。
  • 我在问题第一次出现时尝试了clang,但无济于事,似乎认为我的代码很好。 (我在运行之前也清理了项目。)当我删除项目中的所有发布调用时,问题似乎完全消失了,但是当我重新启动应用程序时,我发现它只是症状暂时消失了。我现在很确定问题不在于过度释放或自动释放。但是在 Obj-C 代码中还有什么其他破坏内存的方法呢?
  • 有很多方法可以破坏事物——毕竟它是 C。但是是什么让您确定这不是保留/释放问题?
【解决方案2】:

尝试在 Valgrind 下的模拟器中运行您的程序:

http://valgrind.org/

以及如何在模拟器下使用:

http://landonf.bikemonkey.org/code/iphone/iPhone_Simulator_Valgrind.20081224.html

您可能需要根据安装位置更改代码示例中的 VALGRIND 路径。

【讨论】:

    【解决方案3】:

    这样的事情对调试来说可能是一个挑战。在其他平台上有一些用于检测越界访问等的工具,所以我认为 iPhone 会有一些工具,但我不知道。

    也许您应该存储数组的两个副本,并比较它们的差异。打印出差异。引入其中一个数组的“垃圾”的性质可能会提示它来自何处。

    也只需检查在此之前运行的代码,然后重新阅读它(或者更好的是,让其他人阅读它)。你可能会发现一个错误。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-11-10
      • 2018-01-26
      • 2012-07-22
      • 1970-01-01
      相关资源
      最近更新 更多