On Fri, 7 Oct 2022 at 10:57, Tom Lane <[email protected]> wrote:
> I poked at this some more by creating a function that intentionally
> does pfree(malloc(N)) for various values of N.
>
> RHEL8, x86_64: the low-order nibble of the header is consistently 0001.
>
> macOS 12.6, arm64: the low-order nibble is consistently 0000.
>
> FreeBSD 13.0, arm64: Usually the low-order nibble is 0000 or 1111,
> but for some smaller values of N it sometimes comes up as 0010.
>
> NetBSD 9.2, amd64: results similar to FreeBSD.
Out of curiosity I tried using the attached on a Windows machine and got:
0: 130951
1: 131061
2: 133110
3: 129053
4: 131061
5: 131067
6: 131070
7: 131203
So it seems pretty much entirely inconsistent on that platform.
Also, on an Ubuntu machine I didn't get the consistent 0001 as you got
on your RHEL machine. There were a very small number of 010's there
too:
0: 0
1: 1048569
2: 7
3: 0
4: 0
5: 0
6: 0
7: 0
Despite Windows not being very consistent here, I think it's a useful
change as if our most common platform (Linux/glibc) is fairly
consistent, then that'll give us wide coverage to track down any buggy
code.
In anycase, even on Windows (assuming it's completely random) we'll
have a 5 out of 8 chance of getting a nice error message if there are
any bad pointers being passed.
David
#include <stdio.h>
#include <stdlib.h>
typedef unsigned long long uint64;
int main(void)
{
size_t count[8] = {0};
size_t n;
for (n = 0; n < 1024*1024; n++)
{
void *ptr = (void *) malloc(n);
uint64 header;
if (!ptr)
{
fprintf(stderr, "OOM\n");
return -1;
}
header = *((uint64 *) ((char *) ptr - sizeof(uint64)));
count[header & 7]++;
free(ptr);
}
for (n = 0; n <= 7; n++)
printf("%zd: %zd\n", n, count[n]);
return 0;
}