I'm developing an iOS app and when I run it on my devices I got lots of the following warnings:
MyApp(2138,0x104338000) malloc: *** can't protect(0x3) region for postlude guard page at 0x104950000
They don't stop the execution but looks scary and probably are related to occasional crash of my app. I googled and only found two pages on the entire web and none of the helps. I wonder if anyone here knows how to fix this?
Edit: here is the product scheme I used:
The error you're seeing comes from Apple's malloc implementation and is due to vm_protect
failing when trying modify memory protection of the guard pages that have been added to your memory allocations.
So it sounds like you've enabled debugmalloc
's MallocGuardEdges
flag (I didn't think debugmalloc
was available on ios devices).
The 0x3
= VM_PROT_READ | VM_PROT_WRITE
in the message is saying that vm_protect
failed to make the page read-write which means that this is happening in response to a free
.
The only documented return codes for vm_protect
are KERN_PROTECTION_FAILURE
and KERN_INVALID_ADDRESS
so at this point I can only guess what happened. Making a page read-write seems like a modest request, for a valid page you wouldn't expect KERN_PROTECTION_FAILURE
, which leaves KERN_INVALID_ADDRESS
, meaning that perhaps your page at 0x104950000
is invalid.
Which would imply a memory stomping bug.
The issue is one-year old, but we ran into the same issue and found this thread. We where able to simplify and reproduce it in latest Xcode 7.3 on Mac with the following piece of C code:
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;
}
This will trigger the malloc_printf() breakpoint in the 2nd for loop (when the reallocations shrink memory) and print:
malloc: *** can't protect(0x3) region for postlude guard page at 0x48ed000
It appears (setting a breakpoint on malloc_printf()) that this happens exactly on the first time that realloc() changes the returned pointer, the total output of above program is:
realloc(p,1249 * 100 = 124900) changes pointer from 0x48b0000 to 0x5000000
realloc(p,2 * 100 = 200) changes pointer from 0x5000000 to 0x240cc60
Playing a bit with combinations of the block size s and number of iterations n it happens at least for 10/50000, 100/5000, 200/5000, ..., it seems when the allocated memory i * s shrinks to around 124000 bytes. Other combinations like 1/200000 don't trigger malloc_printf().
Given the simplicity of this code snippet, we believe that this is a bug in Apple's malloc debug implementation.... or the message is supposed to be some informative (internal) message rather than trying to signal a real memory issue.
(A version of) the source code for Apple's malloc implementation can be found here http://www.opensource.apple.com/source/Libc/Libc-391.4.2/gen/scalable_malloc.c?txt. We are considering to raise with Apple Developer Centre...
So in short the answer is that it might very well not be a memory stomping bug in your code, but instead an issue in de malloc debug code itself, in which case you need to just ignore the message.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With