如何修复" malloc:不能保护区域的后置保护页面" iOS上的警告

时间:2015-04-22 22:17:48

标签: ios objective-c malloc

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

MyApp(2138,0x104338000)malloc:***无法保护(0x3)区域的后置保护页面为0x104950000

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

修改:这是我使用的产品方案:

2 个答案:

答案 0 :(得分:5)

您看到的错误来自Apple's malloc implementation,并且由于count(id)在尝试修改已添加到内存分配的防护页面的内存保护时失败。

听起来你已启用vm_protect的{​​{1}}标记(我认为ios设备上没有debugmalloc)。

消息中的MallocGuardEdges = VM_PROT_READ | VM_PROT_WRITE表示debugmalloc无法使页面进行读写,这意味着这是为了响应0x3而发生的。

唯一记录的return codes for vm_protectvm_protectfree所以此时我只能猜到发生了什么。使页面读写似乎是一个适度的请求,对于一个你不期望的有效页面KERN_PROTECTION_FAILURE,它离开KERN_INVALID_ADDRESS,这意味着你KERN_PROTECTION_FAILURE的页面可能无效。< / p>

这意味着内存踩踏错误。

答案 1 :(得分:1)

这个问题已经有一年了,但是我们遇到了同样的问题,发现了这个问题。我们能够使用以下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;
    }

这将触发2nd 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()。

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

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

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