Bug 407589 - [Linux] Add support for C11 aligned_alloc() and GNU reallocarray()
Summary: [Linux] Add support for C11 aligned_alloc() and GNU reallocarray()
Status: RESOLVED FIXED
Alias: None
Product: valgrind
Classification: Developer tools
Component: memcheck (show other bugs)
Version: unspecified
Platform: Other Linux
: NOR wishlist
Target Milestone: ---
Assignee: Paul Floyd
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2019-05-16 09:31 UTC by Yann Droneaud
Modified: 2021-10-09 13:06 UTC (History)
2 users (show)

See Also:
Latest Commit:
Version Fixed In:


Attachments
Patch for algned_alloc support (7.76 KB, patch)
2020-03-28 13:45 UTC, Paul Floyd
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Yann Droneaud 2019-05-16 09:31:30 UTC
According to http://www.valgrind.org/docs/manual/mc-manual.html#mc-manual.together

"Memcheck intercepts calls to malloc, calloc, realloc, valloc, memalign, free, new, new[], delete and delete[]"

It should be noted Valgrind has support for more calls than listed in documentation, namely:

- posix_memalign()
- pvalloc()
- valloc()

But it doesn't have explicit support for C11 aligned allocation function:

- void *aligned_alloc (size_t alignment, size_t size);

  http://man7.org/linux/man-pages/man3/reallocarray.3.html

And GNU reallocate array function:

- void *reallocarray (void *ptr, size_t nmemb, size_t size);

  http://man7.org/linux/man-pages/man3/reallocarray.3.html
Comment 1 Yann Droneaud 2019-05-16 09:45:22 UTC
(In reply to Yann Droneaud from comment #0)

> And GNU reallocate array function:
> 
> - void *reallocarray (void *ptr, size_t nmemb, size_t size);
> 
>   http://man7.org/linux/man-pages/man3/reallocarray.3.html

It's originally an OpenBSD extension, which is also available at least in FreeBSD and NetBSD

OpenBSD: https://man.openbsd.org/reallocarray.3
FreeBSD: https://www.freebsd.org/cgi/man.cgi?query=reallocarray
NetBSD:  http://netbsd.gw.com/cgi-bin/man-cgi?reallocarray
Comment 2 Yann Droneaud 2019-05-16 09:46:22 UTC
(In reply to Yann Droneaud from comment #0)

> But it doesn't have explicit support for C11 aligned allocation function:
> 
> - void *aligned_alloc (size_t alignment, size_t size);
> 

Correct link: http://man7.org/linux/man-pages/man3/aligned_alloc.3.html
Comment 3 Yann Droneaud 2019-05-16 09:57:54 UTC
More about those functions in glibc documentation:

http://www.gnu.org/software/libc/manual/html_node/Summary-of-Malloc.html
Comment 4 Paul Floyd 2020-03-06 21:07:33 UTC
I'll take a look at this.
Comment 5 Paul Floyd 2020-03-10 15:48:26 UTC
A more authoritative reference

https://en.cppreference.com/w/c/memory/aligned_alloc
Comment 6 Paul Floyd 2020-03-28 13:41:57 UTC
I'll look at reallocarray another day on FreeBSD (not a high priority for me).

For aligned_alloc, I don't think that this will work well. The problem is that aligned_alloc and and memalign alias the same function on Linux GNU libc, i.e., 

paulf> nm /lib64/libc.so.6 | grep align | grep 0000000000081920 
0000000000081920 W aligned_alloc 
0000000000081920 t __GI___libc_memalign 
0000000000081920 T __libc_memalign 
0000000000081920 W memalign 
0000000000081920 t __memalign

Unless I'm much mistaken Valgrind can't redirect from one function address to two different functions. This limits the usefulness to either a libc with separate implementations of memalign/aligned_alloc or a replacement function.

In practice this means that aligned_alloc uses will just show up as memaligns. I'll add a patch for this, but it will be of very limited use.

I suggest simply updating the docs.
Comment 7 Paul Floyd 2020-03-28 13:45:01 UTC
Created attachment 127060 [details]
Patch for algned_alloc support
Comment 8 Paul Floyd 2020-03-28 13:47:11 UTC
Finally, I did start writing some regression tests, for instance

// example from here https://en.cppreference.com/w/c/memory/aligned_alloc

#include <stdlib.h>
#include <stdio.h>

int main(void)
{
    int *p1 = malloc(10*sizeof *p1);
    printf("default-aligned addr:   %p\n", (void*)p1);
    free(p1);
 
    int *p2 = aligned_alloc(1024, 1024*sizeof *p2);
    printf("1024-byte aligned addr: %p\n", (void*)p2);
    if ((size_t)p2 % 1024U)
        printf("p2 not aligned!\n");
    free(p2);
}
Comment 9 Paul Floyd 2020-03-28 14:21:56 UTC
Even more finally, this patch is worthwhile on FreeBSD.
Comment 10 Paul Floyd 2020-10-20 10:31:40 UTC
Currently, in practice I don't see much benefit in adding reallocarray.

The glibc implementation just uses realloc:
https://code.woboq.org/userspace/glibc/malloc/reallocarray.c.html

So does the FreeBSD implementation:

https://github.com/freebsd/freebsd/blob/master/lib/libc/stdlib/reallocarray.c

The only difference would be callstacks that are a tiny bit cleaner.
Comment 11 Paul Floyd 2021-09-28 08:52:11 UTC
The fix for aligned_alloc is likely to land along with support for FreeBSD. I will close this item then. If you feel that there is a strong need for reallocarray please open a new item and I'll take a look.
Comment 12 Paul Floyd 2021-10-09 13:06:55 UTC
This should now be fixed along with the merges for FreeBSD support.