diff options
author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2023-11-01 09:56:08 -0300 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2023-11-07 10:27:20 -0300 |
commit | fee9e40a8da75fad9717668f6dddcc26f3feca2d (patch) | |
tree | 318af06cfcad98364192c6b01bb2a0ed6a08b577 /elf | |
parent | 6afce56c197ee83520994a2c94a82c2ca2bce9fa (diff) | |
download | glibc-fee9e40a8da75fad9717668f6dddcc26f3feca2d.zip glibc-fee9e40a8da75fad9717668f6dddcc26f3feca2d.tar.gz glibc-fee9e40a8da75fad9717668f6dddcc26f3feca2d.tar.bz2 |
malloc: Decorate malloc maps
Add anonymous mmap annotations on loader malloc, malloc when it
allocates memory with mmap, and on malloc arena. The /proc/self/maps
will now print:
[anon: glibc: malloc arena]
[anon: glibc: malloc]
[anon: glibc: loader malloc]
On arena allocation, glibc annotates only the read/write mapping.
Checked on x86_64-linux-gnu and aarch64-linux-gnu.
Reviewed-by: DJ Delorie <dj@redhat.com>
Diffstat (limited to 'elf')
-rw-r--r-- | elf/Makefile | 4 | ||||
-rw-r--r-- | elf/dl-minimal-malloc.c | 2 | ||||
-rw-r--r-- | elf/tst-decorate-maps.c | 36 |
3 files changed, 42 insertions, 0 deletions
diff --git a/elf/Makefile b/elf/Makefile index 33f88ba..328dbe8 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -2983,3 +2983,7 @@ $(objpfx)tst-dlclose-lazy.out: \ $(objpfx)tst-dlclose-lazy-mod1.so $(objpfx)tst-dlclose-lazy-mod2.so $(objpfx)tst-decorate-maps: $(shared-thread-library) + +tst-decorate-maps-ENV = \ + GLIBC_TUNABLES=glibc.malloc.arena_max=8:glibc.malloc.mmap_threshold=1024 +tst-decorate-maps-ARGS = 8 diff --git a/elf/dl-minimal-malloc.c b/elf/dl-minimal-malloc.c index 2754964..da36986 100644 --- a/elf/dl-minimal-malloc.c +++ b/elf/dl-minimal-malloc.c @@ -26,6 +26,7 @@ #include <string.h> #include <ldsodefs.h> #include <malloc/malloc-internal.h> +#include <setvmaname.h> static void *alloc_ptr, *alloc_end, *alloc_last_block; @@ -60,6 +61,7 @@ __minimal_malloc (size_t n) MAP_ANON|MAP_PRIVATE, -1, 0); if (page == MAP_FAILED) return NULL; + __set_vma_name (page, nup, " glibc: loader malloc"); if (page != alloc_end) alloc_ptr = page; alloc_end = page + nup; diff --git a/elf/tst-decorate-maps.c b/elf/tst-decorate-maps.c index b40a0e9..b0ea65f 100644 --- a/elf/tst-decorate-maps.c +++ b/elf/tst-decorate-maps.c @@ -32,15 +32,21 @@ static pthread_barrier_t b; +static int expected_n_arenas; + static void * tf (void *closure) { + void *p = xmalloc (1024); + /* Wait the thread startup, so thread stack is allocated. */ xpthread_barrier_wait (&b); /* Wait the test to read the process mapping. */ xpthread_barrier_wait (&b); + free (p); + return NULL; } @@ -48,6 +54,9 @@ struct proc_maps_t { int n_def_threads; int n_user_threads; + int n_arenas; + int n_malloc_mmap; + int n_loader_malloc_mmap; }; static struct proc_maps_t @@ -69,6 +78,12 @@ read_proc_maps (void) r.n_def_threads++; else if (strstr (line, "[anon: glibc: pthread user stack:") != NULL) r.n_user_threads++; + else if (strstr (line, "[anon: glibc: malloc arena]") != NULL) + r.n_arenas++; + else if (strstr (line, "[anon: glibc: malloc]") != NULL) + r.n_malloc_mmap++; + else if (strstr (line, "[anon: glibc: loader malloc]") != NULL) + r.n_loader_malloc_mmap++; } free (line); xfclose (f); @@ -90,6 +105,9 @@ do_test_threads (bool set_guard) xpthread_barrier_init (&b, NULL, num_threads + 1); + /* Issue a large malloc to trigger a mmap call. */ + void *p = xmalloc (256 * 1024); + pthread_t thr[num_threads]; { int i = 0; @@ -128,6 +146,10 @@ do_test_threads (bool set_guard) struct proc_maps_t r = read_proc_maps (); TEST_COMPARE (r.n_def_threads, num_def_threads); TEST_COMPARE (r.n_user_threads, num_user_threads); + TEST_COMPARE (r.n_arenas, expected_n_arenas); + TEST_COMPARE (r.n_malloc_mmap, 1); + /* On some architectures the loader might use more than one page. */ + TEST_VERIFY (r.n_loader_malloc_mmap >= 1); } /* Let the threads finish. */ @@ -140,8 +162,22 @@ do_test_threads (bool set_guard) struct proc_maps_t r = read_proc_maps (); TEST_COMPARE (r.n_def_threads, 0); TEST_COMPARE (r.n_user_threads, 0); + TEST_COMPARE (r.n_arenas, expected_n_arenas); + TEST_COMPARE (r.n_malloc_mmap, 1); + TEST_VERIFY (r.n_loader_malloc_mmap >= 1); } + + free (p); +} + +static void +do_prepare (int argc, char *argv[]) +{ + TEST_VERIFY_EXIT (argc == 2); + expected_n_arenas = strtol (argv[1], NULL, 10); + expected_n_arenas = expected_n_arenas - 1; } +#define PREPARE do_prepare static int do_test (void) |