【问题标题】:how to fix "malloc: can't protect region for postlude guard page" warnings on iOS如何修复 iOS 上的“malloc:无法保护后奏保护页面的区域”警告
【发布时间】:2015-06-30 20:11:42
【问题描述】:

我正在开发一个 iOS 应用,当我在我的设备上运行它时,我收到了很多以下警告:

MyApp(2138,0x104338000) malloc: *** can't protect(0x3) region for postlude guard page at 0x104950000

它们不会停止执行,但看起来很吓人,可能与我的应用程序偶尔崩溃有关。我用谷歌搜索,在整个网络上只找到了两个页面,没有任何帮助。我想知道这里是否有人知道如何解决这个问题?

编辑:这是我使用的产品方案:

【问题讨论】:

    标签: ios objective-c malloc


    【解决方案1】:

    您看到的错误来自Apple's malloc implementation,是由于vm_protect 在尝试修改已添加到内存分配的保护页的内存保护时失败。

    听起来你已经启用了debugmallocMallocGuardEdges 标志(我不认为debugmalloc 在ios 设备上可用)。

    消息中的0x3 = VM_PROT_READ | VM_PROT_WRITE 表示vm_protect 未能使页面读写,这意味着这是响应free 而发生的。

    唯一记录在案的return codes for vm_protectKERN_PROTECTION_FAILUREKERN_INVALID_ADDRESS,所以此时我只能猜测发生了什么。使页面读写似乎是一个适度的请求,对于一个您不会期望KERN_PROTECTION_FAILURE 的有效页面,它会留下KERN_INVALID_ADDRESS,这意味着您在0x104950000 的页面可能是无效的。

    这意味着内存踩踏错误。

    【讨论】:

    • 您好,感谢您的详尽回答。我想知道是否有像 valgrind 这样的工具可以提供有关内存踩踏错误的更多详细信息?或者有没有关于如何手动跟踪它的好教程?
    • 显然 dev valgrind 在 osx yosemite 上工作! stackoverflow.com/questions/26564125/yosemite-and-valgrind
    【解决方案2】:

    这个问题已经存在一年了,但我们遇到了同样的问题并找到了这个帖子。我们可以使用以下 C 代码在 Mac 上的最新 Xcode 7.3 中简化和重现它:

    int main(int argc, char *argv[])
        {
        const int s = 100, n = 5000;
        int i;
        void *p = malloc(s);
        for (i = 2 ; i <= n ; i++)
            p = realloc(p,i * s);
        for (i = n - 1 ; i > 0 ; i--)
            {
            void *newp = realloc(p,i * s);
            if (newp != p)
                printf("realloc(p,%d * %d = %d) changes pointer from %p to %p\n",i,s,i * s,p,newp);
            p = newp;
            }
        free(p);
        return 0;
        }
    

    这将触发第二个 for 循环中的 malloc_printf() 断点(当重新分配缩小内存时)并打印:

    malloc: *** can't protect(0x3) region for postlude guard page at 0x48ed000
    

    看起来(在 malloc_printf() 上设置断点)这恰好发生在 realloc() 第一次更改返回的指针时,上述程序的总输出为:

    realloc(p,1249 * 100 = 124900) changes pointer from 0x48b0000 to 0x5000000
    realloc(p,2 * 100 = 200) changes pointer from 0x5000000 to 0x240cc60
    

    使用块大小 s 和迭代次数 n 的组合玩一点,它至少会发生 10/50000、100/5000、200/5000,...,似乎当分配的内存 i * s 缩小到大约 124000 字节。 1/200000 等其他组合不会触发 malloc_printf()。

    鉴于此代码 sn-p 的简单性,我们认为这是 Apple 的 malloc 调试实现中的一个错误......或者该消息应该是一些信息性(内部)消息,而不是试图发出真实内存的信号问题。

    Apple 的 malloc 实现的源代码(一个版本)可以在这里找到http://www.opensource.apple.com/source/Libc/Libc-391.4.2/gen/scalable_malloc.c?txt。我们正在考虑向 Apple 开发者中心筹集资金...

    所以简而言之,答案很可能不是代码中的内存踩踏错误,而是 de malloc 调试代码本身的问题,在这种情况下,您只需忽略该消息。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-07-07
      • 2022-10-18
      • 1970-01-01
      • 1970-01-01
      • 2014-01-13
      • 2016-06-20
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多