]>
Commit | Line | Data |
---|---|---|
9c96c87d | 1 | /* Check GLIBC_TUNABLES parsing. |
dff8da6b | 2 | Copyright (C) 2023-2024 Free Software Foundation, Inc. |
9c96c87d AZ |
3 | This file is part of the GNU C Library. |
4 | ||
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. | |
9 | ||
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. | |
14 | ||
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/>. */ | |
18 | ||
19 | #include <array_length.h> | |
20 | #include <dl-tunables.h> | |
21 | #include <getopt.h> | |
22 | #include <intprops.h> | |
23 | #include <stdint.h> | |
24 | #include <stdlib.h> | |
25 | #include <support/capture_subprocess.h> | |
26 | #include <support/check.h> | |
27 | ||
28 | static int restart; | |
29 | #define CMDLINE_OPTIONS \ | |
30 | { "restart", no_argument, &restart, 1 }, | |
31 | ||
32 | static const struct test_t | |
33 | { | |
2a969b53 AZ |
34 | const char *name; |
35 | const char *value; | |
9c96c87d AZ |
36 | int32_t expected_malloc_check; |
37 | size_t expected_mmap_threshold; | |
38 | int32_t expected_perturb; | |
39 | } tests[] = | |
40 | { | |
41 | /* Expected tunable format. */ | |
42 | { | |
2a969b53 | 43 | "GLIBC_TUNABLES", |
9c96c87d AZ |
44 | "glibc.malloc.check=2", |
45 | 2, | |
46 | 0, | |
47 | 0, | |
48 | }, | |
49 | { | |
2a969b53 | 50 | "GLIBC_TUNABLES", |
9c96c87d AZ |
51 | "glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096", |
52 | 2, | |
53 | 4096, | |
54 | 0, | |
55 | }, | |
f94446c3 AZ |
56 | { |
57 | "GLIBC_TUNABLES", | |
58 | "glibc.malloc.mmap_threshold=-1", | |
59 | 0, | |
60 | SIZE_MAX, | |
61 | 0, | |
62 | }, | |
9c96c87d AZ |
63 | /* Empty tunable are ignored. */ |
64 | { | |
2a969b53 | 65 | "GLIBC_TUNABLES", |
9c96c87d AZ |
66 | "glibc.malloc.check=2::glibc.malloc.mmap_threshold=4096", |
67 | 2, | |
68 | 4096, | |
69 | 0, | |
70 | }, | |
71 | /* As well empty values. */ | |
72 | { | |
2a969b53 | 73 | "GLIBC_TUNABLES", |
9c96c87d AZ |
74 | "glibc.malloc.check=:glibc.malloc.mmap_threshold=4096", |
75 | 0, | |
76 | 4096, | |
77 | 0, | |
78 | }, | |
79 | /* Tunable are processed from left to right, so last one is the one set. */ | |
80 | { | |
2a969b53 | 81 | "GLIBC_TUNABLES", |
9c96c87d AZ |
82 | "glibc.malloc.check=1:glibc.malloc.check=2", |
83 | 2, | |
84 | 0, | |
85 | 0, | |
86 | }, | |
87 | { | |
2a969b53 | 88 | "GLIBC_TUNABLES", |
9c96c87d AZ |
89 | "glibc.malloc.check=1:glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096", |
90 | 2, | |
91 | 4096, | |
92 | 0, | |
93 | }, | |
94 | { | |
2a969b53 | 95 | "GLIBC_TUNABLES", |
9c96c87d AZ |
96 | "glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096:glibc.malloc.check=1", |
97 | 1, | |
98 | 4096, | |
99 | 0, | |
100 | }, | |
101 | /* 0x800 is larger than tunable maxval (0xff), so the tunable is unchanged. */ | |
102 | { | |
2a969b53 | 103 | "GLIBC_TUNABLES", |
9c96c87d AZ |
104 | "glibc.malloc.perturb=0x800", |
105 | 0, | |
106 | 0, | |
107 | 0, | |
108 | }, | |
109 | { | |
2a969b53 | 110 | "GLIBC_TUNABLES", |
9c96c87d AZ |
111 | "glibc.malloc.perturb=0x55", |
112 | 0, | |
113 | 0, | |
114 | 0x55, | |
115 | }, | |
116 | /* Out of range values are just ignored. */ | |
117 | { | |
2a969b53 | 118 | "GLIBC_TUNABLES", |
9c96c87d AZ |
119 | "glibc.malloc.perturb=0x800:glibc.malloc.mmap_threshold=4096", |
120 | 0, | |
121 | 4096, | |
122 | 0, | |
123 | }, | |
124 | /* Invalid keys are ignored. */ | |
125 | { | |
2a969b53 | 126 | "GLIBC_TUNABLES", |
9c96c87d AZ |
127 | ":glibc.malloc.garbage=2:glibc.malloc.check=1", |
128 | 1, | |
129 | 0, | |
130 | 0, | |
131 | }, | |
132 | { | |
2a969b53 | 133 | "GLIBC_TUNABLES", |
9c96c87d AZ |
134 | "glibc.malloc.perturb=0x800:not_valid.malloc.check=2:glibc.malloc.mmap_threshold=4096", |
135 | 0, | |
136 | 4096, | |
137 | 0, | |
138 | }, | |
139 | { | |
2a969b53 | 140 | "GLIBC_TUNABLES", |
9c96c87d AZ |
141 | "glibc.not_valid.check=2:glibc.malloc.mmap_threshold=4096", |
142 | 0, | |
143 | 4096, | |
144 | 0, | |
145 | }, | |
146 | { | |
2a969b53 | 147 | "GLIBC_TUNABLES", |
9c96c87d AZ |
148 | "not_valid.malloc.check=2:glibc.malloc.mmap_threshold=4096", |
149 | 0, | |
150 | 4096, | |
151 | 0, | |
152 | }, | |
153 | /* Invalid subkeys are ignored. */ | |
154 | { | |
2a969b53 | 155 | "GLIBC_TUNABLES", |
9c96c87d AZ |
156 | "glibc.malloc.garbage=2:glibc.maoc.mmap_threshold=4096:glibc.malloc.check=2", |
157 | 2, | |
158 | 0, | |
159 | 0, | |
160 | }, | |
161 | { | |
2a969b53 | 162 | "GLIBC_TUNABLES", |
9c96c87d AZ |
163 | "glibc.malloc.check=4:glibc.malloc.garbage=2:glibc.maoc.mmap_threshold=4096", |
164 | 0, | |
165 | 0, | |
166 | 0, | |
167 | }, | |
168 | { | |
2a969b53 | 169 | "GLIBC_TUNABLES", |
9c96c87d AZ |
170 | "not_valid.malloc.check=2", |
171 | 0, | |
172 | 0, | |
173 | 0, | |
174 | }, | |
175 | { | |
2a969b53 | 176 | "GLIBC_TUNABLES", |
9c96c87d AZ |
177 | "glibc.not_valid.check=2", |
178 | 0, | |
179 | 0, | |
180 | 0, | |
181 | }, | |
182 | /* An ill-formatted tunable in the for key=key=value will considere the | |
183 | value as 'key=value' (which can not be parsed as an integer). */ | |
184 | { | |
2a969b53 | 185 | "GLIBC_TUNABLES", |
9c96c87d AZ |
186 | "glibc.malloc.mmap_threshold=glibc.malloc.mmap_threshold=4096", |
187 | 0, | |
188 | 0, | |
189 | 0, | |
190 | }, | |
680c597e | 191 | /* Ill-formatted tunables string is not parsed. */ |
9c96c87d | 192 | { |
2a969b53 | 193 | "GLIBC_TUNABLES", |
9c96c87d | 194 | "glibc.malloc.mmap_threshold=glibc.malloc.mmap_threshold=4096:glibc.malloc.check=2", |
b4cf6cac | 195 | 0, |
9c96c87d AZ |
196 | 0, |
197 | 0, | |
198 | }, | |
9c96c87d | 199 | { |
2a969b53 | 200 | "GLIBC_TUNABLES", |
9c96c87d | 201 | "glibc.malloc.check=2=2", |
b4cf6cac | 202 | 0, |
9c96c87d AZ |
203 | 0, |
204 | 0, | |
205 | }, | |
206 | { | |
2a969b53 | 207 | "GLIBC_TUNABLES", |
9c96c87d | 208 | "glibc.malloc.check=2=2:glibc.malloc.mmap_threshold=4096", |
b4cf6cac AZ |
209 | 0, |
210 | 0, | |
211 | 0, | |
212 | }, | |
213 | { | |
2a969b53 | 214 | "GLIBC_TUNABLES", |
b4cf6cac AZ |
215 | "glibc.malloc.check=2=2:glibc.malloc.check=2", |
216 | 0, | |
217 | 0, | |
218 | 0, | |
219 | }, | |
b4cf6cac | 220 | { |
2a969b53 | 221 | "GLIBC_TUNABLES", |
b4cf6cac | 222 | "glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096=4096", |
b4cf6cac | 223 | 0, |
9c96c87d | 224 | 0, |
680c597e AZ |
225 | 0, |
226 | }, | |
227 | { | |
2a969b53 | 228 | "GLIBC_TUNABLES", |
680c597e AZ |
229 | "glibc.malloc.check=2:glibc.malloc.mmap_threshold=4096=4096", |
230 | 0, | |
231 | 0, | |
232 | 0, | |
233 | }, | |
f94446c3 AZ |
234 | /* Invalid numbers are ignored. */ |
235 | { | |
236 | "GLIBC_TUNABLES", | |
237 | "glibc.malloc.check=abc:glibc.malloc.mmap_threshold=4096", | |
238 | 0, | |
239 | 4096, | |
240 | 0, | |
241 | }, | |
242 | { | |
243 | "GLIBC_TUNABLES", | |
244 | "glibc.malloc.check=2:glibc.malloc.mmap_threshold=abc", | |
245 | 2, | |
246 | 0, | |
247 | 0, | |
248 | }, | |
249 | { | |
250 | "GLIBC_TUNABLES", | |
251 | /* SIZE_MAX + 1 */ | |
252 | "glibc.malloc.mmap_threshold=18446744073709551616", | |
253 | 0, | |
254 | 0, | |
255 | 0, | |
256 | }, | |
2a969b53 AZ |
257 | /* Also check some tunable aliases. */ |
258 | { | |
259 | "MALLOC_CHECK_", | |
260 | "2", | |
261 | 2, | |
262 | 0, | |
263 | 0, | |
264 | }, | |
265 | { | |
266 | "MALLOC_MMAP_THRESHOLD_", | |
267 | "4096", | |
268 | 0, | |
269 | 4096, | |
270 | 0, | |
271 | }, | |
272 | { | |
273 | "MALLOC_PERTURB_", | |
274 | "0x55", | |
275 | 0, | |
276 | 0, | |
277 | 0x55, | |
278 | }, | |
279 | /* 0x800 is larger than tunable maxval (0xff), so the tunable is unchanged. */ | |
280 | { | |
281 | "MALLOC_PERTURB_", | |
282 | "0x800", | |
283 | 0, | |
284 | 0, | |
285 | 0, | |
286 | }, | |
9c96c87d AZ |
287 | }; |
288 | ||
289 | static int | |
290 | handle_restart (int i) | |
291 | { | |
292 | TEST_COMPARE (tests[i].expected_malloc_check, | |
293 | TUNABLE_GET_FULL (glibc, malloc, check, int32_t, NULL)); | |
294 | TEST_COMPARE (tests[i].expected_mmap_threshold, | |
295 | TUNABLE_GET_FULL (glibc, malloc, mmap_threshold, size_t, NULL)); | |
296 | TEST_COMPARE (tests[i].expected_perturb, | |
297 | TUNABLE_GET_FULL (glibc, malloc, perturb, int32_t, NULL)); | |
298 | return 0; | |
299 | } | |
300 | ||
301 | static int | |
302 | do_test (int argc, char *argv[]) | |
303 | { | |
304 | /* We must have either: | |
305 | - One our fource parameters left if called initially: | |
306 | + path to ld.so optional | |
307 | + "--library-path" optional | |
308 | + the library path optional | |
309 | + the application name | |
310 | + the test to check */ | |
311 | ||
312 | TEST_VERIFY_EXIT (argc == 2 || argc == 5); | |
313 | ||
314 | if (restart) | |
315 | return handle_restart (atoi (argv[1])); | |
316 | ||
317 | char nteststr[INT_BUFSIZE_BOUND (int)]; | |
318 | ||
319 | char *spargv[10]; | |
320 | { | |
321 | int i = 0; | |
322 | for (; i < argc - 1; i++) | |
323 | spargv[i] = argv[i + 1]; | |
324 | spargv[i++] = (char *) "--direct"; | |
325 | spargv[i++] = (char *) "--restart"; | |
326 | spargv[i++] = nteststr; | |
327 | spargv[i] = NULL; | |
328 | } | |
329 | ||
330 | for (int i = 0; i < array_length (tests); i++) | |
331 | { | |
332 | snprintf (nteststr, sizeof nteststr, "%d", i); | |
333 | ||
2a969b53 AZ |
334 | printf ("[%d] Spawned test for %s=%s\n", |
335 | i, | |
336 | tests[i].name, | |
337 | tests[i].value); | |
338 | setenv (tests[i].name, tests[i].value, 1); | |
9c96c87d AZ |
339 | struct support_capture_subprocess result |
340 | = support_capture_subprogram (spargv[0], spargv); | |
341 | support_capture_subprocess_check (&result, "tst-tunables", 0, | |
342 | sc_allow_stderr); | |
343 | support_capture_subprocess_free (&result); | |
2a969b53 | 344 | unsetenv (tests[i].name); |
9c96c87d AZ |
345 | } |
346 | ||
347 | return 0; | |
348 | } | |
349 | ||
350 | #define TEST_FUNCTION_ARGV do_test | |
351 | #include <support/test-driver.c> |