当我用c++编程时,当我发现内存损坏发生时,我的首选是启动Valgrind,看看它是否捕获了一行某处的无效写入。现在我编写的代码应该运行在32位iphone上,我的开发环境是OSX Mavericks上的Xcode, Valgrind似乎不再是一个选择;即使不考虑架构不匹配,google也会发现许多Valgrind和Mavericks之间不兼容的报告,尤其是32位二进制文件。然而,我在Xcode Instruments中找不到任何具有类似功能的东西-内存泄漏检测器都很好,但是没有找到那些卑鄙的内存损坏。
有人知道在开发/调试iOS应用程序时检测无效写入的好工具吗?
使用Xcode提供的Guard Malloc。
点击您的应用程序名称,在顶部按钮的右侧,弹出项目中的方案列表。选择"编辑方案…"在底部。在弹出的对话框中选择"Diagnostics"选项卡。在这里,勾选启用Guard Malloc。
苹果的文档详细说明了它和其他一些选项的作用,但是当你运行时记录到控制台的文本几乎解释了这一切:
Allocations will be placed on 16 byte boundaries.
- Some buffer overruns may not be noticed.
- Applications using vector instructions (e.g., SSE) should work.
每个新的分配将在一个新的页面开始。页面将通过设置适当的MMU标志框起来,以便越界访问引发EXC_BAD_ACCESS。因此,它将在访问发生的那一刻捕获90%的内存访问错误,其代价是由于缓存效率低下,程序运行速度明显变慢。
讽刺的是,这段代码:
char *array = (char *)malloc(17);
array[31] = 9;
…不管有没有Guard Malloc,都不会引发异常。这段代码:
char *array = (char *)malloc(17);
array[32] = 9;
…通常不会引发异常。如果启用了Guard Malloc,它将在执行第二行时引发异常。
所以它不像Valgrind那样彻底,但它只需要一秒钟就可以打开,并且可能会发现重大错误。