nptl: Decorate thread stack on pthread_create
[glibc.git] / elf / tst-decorate-maps.c
blobb40a0e9b49ef9350efd6cf3afa3cdae673423b3b
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 void *
36 tf (void *closure)
38 /* Wait the thread startup, so thread stack is allocated. */
39 xpthread_barrier_wait (&b);
41 /* Wait the test to read the process mapping. */
42 xpthread_barrier_wait (&b);
44 return NULL;
47 struct proc_maps_t
49 int n_def_threads;
50 int n_user_threads;
53 static struct proc_maps_t
54 read_proc_maps (void)
56 if (test_verbose)
57 printf ("=== print process %jd memory mapping ===\n",
58 (intmax_t) getpid ());
59 struct proc_maps_t r = { 0 };
61 FILE *f = xfopen ("/proc/self/maps", "r");
62 char *line = NULL;
63 size_t line_len = 0;
64 while (xgetline (&line, &line_len, f))
66 if (test_verbose)
67 printf ("%s", line);
68 if (strstr (line, "[anon: glibc: pthread stack:") != NULL)
69 r.n_def_threads++;
70 else if (strstr (line, "[anon: glibc: pthread user stack:") != NULL)
71 r.n_user_threads++;
73 free (line);
74 xfclose (f);
76 if (test_verbose)
77 printf ("===\n");
78 return r;
81 static void
82 do_test_threads (bool set_guard)
84 enum
86 num_def_threads = 8,
87 num_user_threads = 2,
88 num_threads = num_def_threads + num_user_threads,
91 xpthread_barrier_init (&b, NULL, num_threads + 1);
93 pthread_t thr[num_threads];
95 int i = 0;
96 for (; i < num_threads - num_user_threads; i++)
98 pthread_attr_t attr;
99 xpthread_attr_init (&attr);
100 /* The guard page is not annotated. */
101 if (!set_guard)
102 xpthread_attr_setguardsize (&attr, 0);
103 thr[i] = xpthread_create (&attr, tf, NULL);
104 xpthread_attr_destroy (&attr);
106 for (; i < num_threads; i++)
108 pthread_attr_t attr;
109 xpthread_attr_init (&attr);
110 size_t stacksize = support_small_thread_stack_size ();
111 void *stack = xmmap (0,
112 stacksize,
113 PROT_READ | PROT_WRITE,
114 MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK,
115 -1);
116 xpthread_attr_setstack (&attr, stack, stacksize);
117 if (!set_guard)
118 xpthread_attr_setguardsize (&attr, 0);
119 thr[i] = xpthread_create (&attr, tf, NULL);
120 xpthread_attr_destroy (&attr);
124 /* Wait all threads to finshed statup and stack allocation. */
125 xpthread_barrier_wait (&b);
128 struct proc_maps_t r = read_proc_maps ();
129 TEST_COMPARE (r.n_def_threads, num_def_threads);
130 TEST_COMPARE (r.n_user_threads, num_user_threads);
133 /* Let the threads finish. */
134 xpthread_barrier_wait (&b);
136 for (int i = 0; i < num_threads; i++)
137 xpthread_join (thr[i]);
140 struct proc_maps_t r = read_proc_maps ();
141 TEST_COMPARE (r.n_def_threads, 0);
142 TEST_COMPARE (r.n_user_threads, 0);
146 static int
147 do_test (void)
149 support_need_proc ("Reads /proc/self/maps to get stack names.");
151 if (!support_set_vma_name_supported ())
152 FAIL_UNSUPPORTED ("kernel does not support PR_SET_VMA_ANON_NAME");
154 do_test_threads (false);
155 do_test_threads (true);
157 return 0;
160 #include <support/test-driver.c>