On Fri, 7 Oct 2022 at 10:57, Tom Lane <t...@sss.pgh.pa.us> 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;
}

Reply via email to