malloc: Decorate malloc maps
[glibc.git] / elf / tst-decorate-maps.c
blobb0ea65ffd7b4aafe3133c802dc9ef472f5f18705
1 /* Check the VMA name decoration.
2 Copyright (C) 2023 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2.1 of the License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public
16 License along with the GNU C Library; if not, see
17 <https://www.gnu.org/licenses/>. */
19 #include <stdlib.h>
20 #include <string.h>
21 #include <support/check.h>
22 #include <support/support.h>
23 #include <support/test-driver.h>
24 #include <support/xstdio.h>
25 #include <support/xthread.h>
26 #include <support/xunistd.h>
27 #include <sys/mman.h>
29 #ifndef MAP_STACK
30 # define MAP_STACK 0
31 #endif
33 static pthread_barrier_t b;
35 static int expected_n_arenas;
37 static void *
38 tf (void *closure)
40 void *p = xmalloc (1024);
42 /* Wait the thread startup, so thread stack is allocated. */
43 xpthread_barrier_wait (&b);
45 /* Wait the test to read the process mapping. */
46 xpthread_barrier_wait (&b);
48 free (p);
50 return NULL;
53 struct proc_maps_t
55 int n_def_threads;
56 int n_user_threads;
57 int n_arenas;
58 int n_malloc_mmap;
59 int n_loader_malloc_mmap;
62 static struct proc_maps_t
63 read_proc_maps (void)
65 if (test_verbose)
66 printf ("=== print process %jd memory mapping ===\n",
67 (intmax_t) getpid ());
68 struct proc_maps_t r = { 0 };
70 FILE *f = xfopen ("/proc/self/maps", "r");
71 char *line = NULL;
72 size_t line_len = 0;
73 while (xgetline (&line, &line_len, f))
75 if (test_verbose)
76 printf ("%s", line);
77 if (strstr (line, "[anon: glibc: pthread stack:") != NULL)
78 r.n_def_threads++;
79 else if (strstr (line, "[anon: glibc: pthread user stack:") != NULL)
80 r.n_user_threads++;
81 else if (strstr (line, "[anon: glibc: malloc arena]") != NULL)
82 r.n_arenas++;
83 else if (strstr (line, "[anon: glibc: malloc]") != NULL)
84 r.n_malloc_mmap++;
85 else if (strstr (line, "[anon: glibc: loader malloc]") != NULL)
86 r.n_loader_malloc_mmap++;
88 free (line);
89 xfclose (f);
91 if (test_verbose)
92 printf ("===\n");
93 return r;
96 static void
97 do_test_threads (bool set_guard)
99 enum
101 num_def_threads = 8,
102 num_user_threads = 2,
103 num_threads = num_def_threads + num_user_threads,
106 xpthread_barrier_init (&b, NULL, num_threads + 1);
108 /* Issue a large malloc to trigger a mmap call. */
109 void *p = xmalloc (256 * 1024);
111 pthread_t thr[num_threads];
113 int i = 0;
114 for (; i < num_threads - num_user_threads; i++)
116 pthread_attr_t attr;
117 xpthread_attr_init (&attr);
118 /* The guard page is not annotated. */
119 if (!set_guard)
120 xpthread_attr_setguardsize (&attr, 0);
121 thr[i] = xpthread_create (&attr, tf, NULL);
122 xpthread_attr_destroy (&attr);
124 for (; i < num_threads; i++)
126 pthread_attr_t attr;
127 xpthread_attr_init (&attr);
128 size_t stacksize = support_small_thread_stack_size ();
129 void *stack = xmmap (0,
130 stacksize,
131 PROT_READ | PROT_WRITE,
132 MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK,
133 -1);
134 xpthread_attr_setstack (&attr, stack, stacksize);
135 if (!set_guard)
136 xpthread_attr_setguardsize (&attr, 0);
137 thr[i] = xpthread_create (&attr, tf, NULL);
138 xpthread_attr_destroy (&attr);
142 /* Wait all threads to finshed statup and stack allocation. */
143 xpthread_barrier_wait (&b);
146 struct proc_maps_t r = read_proc_maps ();
147 TEST_COMPARE (r.n_def_threads, num_def_threads);
148 TEST_COMPARE (r.n_user_threads, num_user_threads);
149 TEST_COMPARE (r.n_arenas, expected_n_arenas);
150 TEST_COMPARE (r.n_malloc_mmap, 1);
151 /* On some architectures the loader might use more than one page. */
152 TEST_VERIFY (r.n_loader_malloc_mmap >= 1);
155 /* Let the threads finish. */
156 xpthread_barrier_wait (&b);
158 for (int i = 0; i < num_threads; i++)
159 xpthread_join (thr[i]);
162 struct proc_maps_t r = read_proc_maps ();
163 TEST_COMPARE (r.n_def_threads, 0);
164 TEST_COMPARE (r.n_user_threads, 0);
165 TEST_COMPARE (r.n_arenas, expected_n_arenas);
166 TEST_COMPARE (r.n_malloc_mmap, 1);
167 TEST_VERIFY (r.n_loader_malloc_mmap >= 1);
170 free (p);
173 static void
174 do_prepare (int argc, char *argv[])
176 TEST_VERIFY_EXIT (argc == 2);
177 expected_n_arenas = strtol (argv[1], NULL, 10);
178 expected_n_arenas = expected_n_arenas - 1;
180 #define PREPARE do_prepare
182 static int
183 do_test (void)
185 support_need_proc ("Reads /proc/self/maps to get stack names.");
187 if (!support_set_vma_name_supported ())
188 FAIL_UNSUPPORTED ("kernel does not support PR_SET_VMA_ANON_NAME");
190 do_test_threads (false);
191 do_test_threads (true);
193 return 0;
196 #include <support/test-driver.c>