]> git.ipfire.org Git - thirdparty/gcc.git/blame - libbacktrace/btest.c
libstdc++: Review _Local_iterator/_Local_const_iterator implementations.
[thirdparty/gcc.git] / libbacktrace / btest.c
CommitLineData
eff02e4f 1/* btest.c -- Test for libbacktrace library
8d9254fc 2 Copyright (C) 2012-2020 Free Software Foundation, Inc.
eff02e4f
ILT
3 Written by Ian Lance Taylor, Google.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are
7met:
8
9 (1) Redistributions of source code must retain the above copyright
84ebf639 10 notice, this list of conditions and the following disclaimer.
eff02e4f
ILT
11
12 (2) Redistributions in binary form must reproduce the above copyright
13 notice, this list of conditions and the following disclaimer in
14 the documentation and/or other materials provided with the
84ebf639
CL
15 distribution.
16
eff02e4f
ILT
17 (3) The name of the author may not be used to
18 endorse or promote products derived from this software without
19 specific prior written permission.
20
21THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31POSSIBILITY OF SUCH DAMAGE. */
32
33/* This program tests the externally visible interfaces of the
34 libbacktrace library. */
35
36#include <assert.h>
eff02e4f
ILT
37#include <stdio.h>
38#include <stdlib.h>
39#include <string.h>
65d0b859 40#include <unistd.h>
eff02e4f
ILT
41
42#include "filenames.h"
43
44#include "backtrace.h"
45#include "backtrace-supported.h"
46
d1609a23 47#include "testlib.h"
eff02e4f
ILT
48
49/* Test the backtrace function with non-inlined functions. */
50
c51b2c8c
TV
51static int test1 (void) __attribute__ ((noinline, noclone, unused));
52static int f2 (int) __attribute__ ((noinline, noclone));
53static int f3 (int, int) __attribute__ ((noinline, noclone));
eff02e4f
ILT
54
55static int
56test1 (void)
57{
58 /* Returning a value here and elsewhere avoids a tailcall which
59 would mess up the backtrace. */
60 return f2 (__LINE__) + 1;
61}
62
63static int
64f2 (int f1line)
65{
66 return f3 (f1line, __LINE__) + 2;
67}
68
69static int
70f3 (int f1line, int f2line)
71{
72 struct info all[20];
73 struct bdata data;
74 int f3line;
75 int i;
76
77 data.all = &all[0];
78 data.index = 0;
79 data.max = 20;
80 data.failed = 0;
81
82 f3line = __LINE__ + 1;
83 i = backtrace_full (state, 0, callback_one, error_callback_one, &data);
84
85 if (i != 0)
86 {
87 fprintf (stderr, "test1: unexpected return value %d\n", i);
88 data.failed = 1;
89 }
90
b8ddd61b
ILT
91 if (data.index < 3)
92 {
93 fprintf (stderr,
94 "test1: not enough frames; got %zu, expected at least 3\n",
95 data.index);
96 data.failed = 1;
97 }
98
d1609a23
ILT
99 check ("test1", 0, all, f3line, "f3", "btest.c", &data.failed);
100 check ("test1", 1, all, f2line, "f2", "btest.c", &data.failed);
101 check ("test1", 2, all, f1line, "test1", "btest.c", &data.failed);
eff02e4f
ILT
102
103 printf ("%s: backtrace_full noinline\n", data.failed ? "FAIL" : "PASS");
104
105 if (data.failed)
106 ++failures;
107
108 return failures;
109}
110
111/* Test the backtrace function with inlined functions. */
112
bd3e497d 113static inline int test2 (void) __attribute__ ((always_inline, unused));
eff02e4f
ILT
114static inline int f12 (int) __attribute__ ((always_inline));
115static inline int f13 (int, int) __attribute__ ((always_inline));
116
117static inline int
118test2 (void)
119{
120 return f12 (__LINE__) + 1;
121}
122
123static inline int
124f12 (int f1line)
125{
126 return f13 (f1line, __LINE__) + 2;
127}
128
129static inline int
130f13 (int f1line, int f2line)
131{
132 struct info all[20];
133 struct bdata data;
134 int f3line;
135 int i;
136
137 data.all = &all[0];
138 data.index = 0;
139 data.max = 20;
140 data.failed = 0;
141
142 f3line = __LINE__ + 1;
143 i = backtrace_full (state, 0, callback_one, error_callback_one, &data);
144
145 if (i != 0)
146 {
147 fprintf (stderr, "test2: unexpected return value %d\n", i);
148 data.failed = 1;
149 }
150
d1609a23
ILT
151 check ("test2", 0, all, f3line, "f13", "btest.c", &data.failed);
152 check ("test2", 1, all, f2line, "f12", "btest.c", &data.failed);
153 check ("test2", 2, all, f1line, "test2", "btest.c", &data.failed);
eff02e4f
ILT
154
155 printf ("%s: backtrace_full inline\n", data.failed ? "FAIL" : "PASS");
156
157 if (data.failed)
158 ++failures;
159
160 return failures;
161}
162
163/* Test the backtrace_simple function with non-inlined functions. */
164
c51b2c8c
TV
165static int test3 (void) __attribute__ ((noinline, noclone, unused));
166static int f22 (int) __attribute__ ((noinline, noclone));
167static int f23 (int, int) __attribute__ ((noinline, noclone));
eff02e4f
ILT
168
169static int
170test3 (void)
171{
172 return f22 (__LINE__) + 1;
173}
174
175static int
176f22 (int f1line)
177{
178 return f23 (f1line, __LINE__) + 2;
179}
180
181static int
182f23 (int f1line, int f2line)
183{
184 uintptr_t addrs[20];
185 struct sdata data;
186 int f3line;
187 int i;
188
189 data.addrs = &addrs[0];
190 data.index = 0;
191 data.max = 20;
192 data.failed = 0;
193
194 f3line = __LINE__ + 1;
195 i = backtrace_simple (state, 0, callback_two, error_callback_two, &data);
196
197 if (i != 0)
198 {
199 fprintf (stderr, "test3: unexpected return value %d\n", i);
200 data.failed = 1;
201 }
202
203 if (!data.failed)
204 {
205 struct info all[20];
206 struct bdata bdata;
207 int j;
208
209 bdata.all = &all[0];
210 bdata.index = 0;
211 bdata.max = 20;
212 bdata.failed = 0;
213
214 for (j = 0; j < 3; ++j)
215 {
216 i = backtrace_pcinfo (state, addrs[j], callback_one,
217 error_callback_one, &bdata);
218 if (i != 0)
219 {
220 fprintf (stderr,
221 ("test3: unexpected return value "
222 "from backtrace_pcinfo %d\n"),
223 i);
224 bdata.failed = 1;
225 }
226 if (!bdata.failed && bdata.index != (size_t) (j + 1))
227 {
228 fprintf (stderr,
229 ("wrong number of calls from backtrace_pcinfo "
230 "got %u expected %d\n"),
231 (unsigned int) bdata.index, j + 1);
232 bdata.failed = 1;
233 }
84ebf639 234 }
eff02e4f 235
d1609a23
ILT
236 check ("test3", 0, all, f3line, "f23", "btest.c", &bdata.failed);
237 check ("test3", 1, all, f2line, "f22", "btest.c", &bdata.failed);
238 check ("test3", 2, all, f1line, "test3", "btest.c", &bdata.failed);
eff02e4f
ILT
239
240 if (bdata.failed)
241 data.failed = 1;
242
243 for (j = 0; j < 3; ++j)
244 {
245 struct symdata symdata;
246
247 symdata.name = NULL;
248 symdata.val = 0;
1f96a712 249 symdata.size = 0;
eff02e4f
ILT
250 symdata.failed = 0;
251
252 i = backtrace_syminfo (state, addrs[j], callback_three,
253 error_callback_three, &symdata);
254 if (i == 0)
255 {
256 fprintf (stderr,
257 ("test3: [%d]: unexpected return value "
258 "from backtrace_syminfo %d\n"),
259 j, i);
260 symdata.failed = 1;
261 }
262
263 if (!symdata.failed)
264 {
265 const char *expected;
266
267 switch (j)
268 {
269 case 0:
270 expected = "f23";
271 break;
272 case 1:
273 expected = "f22";
274 break;
275 case 2:
276 expected = "test3";
277 break;
068ef6d1 278 default:
eff02e4f
ILT
279 assert (0);
280 }
281
282 if (symdata.name == NULL)
283 {
284 fprintf (stderr, "test3: [%d]: NULL syminfo name\n", j);
285 symdata.failed = 1;
286 }
287 /* Use strncmp, not strcmp, because GCC might create a
288 clone. */
289 else if (strncmp (symdata.name, expected, strlen (expected))
290 != 0)
291 {
292 fprintf (stderr,
293 ("test3: [%d]: unexpected syminfo name "
294 "got %s expected %s\n"),
295 j, symdata.name, expected);
296 symdata.failed = 1;
297 }
298 }
299
300 if (symdata.failed)
301 data.failed = 1;
302 }
303 }
304
305 printf ("%s: backtrace_simple noinline\n", data.failed ? "FAIL" : "PASS");
306
307 if (data.failed)
308 ++failures;
309
310 return failures;
311}
312
313/* Test the backtrace_simple function with inlined functions. */
314
bd3e497d 315static inline int test4 (void) __attribute__ ((always_inline, unused));
eff02e4f
ILT
316static inline int f32 (int) __attribute__ ((always_inline));
317static inline int f33 (int, int) __attribute__ ((always_inline));
318
319static inline int
320test4 (void)
321{
322 return f32 (__LINE__) + 1;
323}
324
325static inline int
326f32 (int f1line)
327{
328 return f33 (f1line, __LINE__) + 2;
329}
330
331static inline int
332f33 (int f1line, int f2line)
333{
334 uintptr_t addrs[20];
335 struct sdata data;
336 int f3line;
337 int i;
338
339 data.addrs = &addrs[0];
340 data.index = 0;
341 data.max = 20;
342 data.failed = 0;
343
344 f3line = __LINE__ + 1;
345 i = backtrace_simple (state, 0, callback_two, error_callback_two, &data);
346
347 if (i != 0)
348 {
349 fprintf (stderr, "test3: unexpected return value %d\n", i);
350 data.failed = 1;
351 }
352
353 if (!data.failed)
354 {
355 struct info all[20];
356 struct bdata bdata;
357
358 bdata.all = &all[0];
359 bdata.index = 0;
360 bdata.max = 20;
361 bdata.failed = 0;
362
363 i = backtrace_pcinfo (state, addrs[0], callback_one, error_callback_one,
364 &bdata);
365 if (i != 0)
366 {
367 fprintf (stderr,
368 ("test4: unexpected return value "
369 "from backtrace_pcinfo %d\n"),
370 i);
371 bdata.failed = 1;
372 }
373
d1609a23
ILT
374 check ("test4", 0, all, f3line, "f33", "btest.c", &bdata.failed);
375 check ("test4", 1, all, f2line, "f32", "btest.c", &bdata.failed);
376 check ("test4", 2, all, f1line, "test4", "btest.c", &bdata.failed);
eff02e4f
ILT
377
378 if (bdata.failed)
379 data.failed = 1;
380 }
381
382 printf ("%s: backtrace_simple inline\n", data.failed ? "FAIL" : "PASS");
383
384 if (data.failed)
385 ++failures;
386
387 return failures;
388}
389
121eb024 390static int test5 (void) __attribute__ ((unused));
e24afc10 391
cfa658e4
ILT
392int global = 1;
393
394static int
395test5 (void)
396{
397 struct symdata symdata;
398 int i;
1f96a712
JJ
399 uintptr_t addr = (uintptr_t) &global;
400
401 if (sizeof (global) > 1)
402 addr += 1;
cfa658e4
ILT
403
404 symdata.name = NULL;
405 symdata.val = 0;
1f96a712 406 symdata.size = 0;
cfa658e4
ILT
407 symdata.failed = 0;
408
1f96a712 409 i = backtrace_syminfo (state, addr, callback_three,
cfa658e4
ILT
410 error_callback_three, &symdata);
411 if (i == 0)
412 {
413 fprintf (stderr,
414 "test5: unexpected return value from backtrace_syminfo %d\n",
415 i);
416 symdata.failed = 1;
417 }
418
419 if (!symdata.failed)
420 {
421 if (symdata.name == NULL)
422 {
423 fprintf (stderr, "test5: NULL syminfo name\n");
424 symdata.failed = 1;
425 }
067aef03
TV
426 else if (!(strncmp (symdata.name, "global", 6) == 0
427 && (symdata.name[6] == '\0'|| symdata.name[6] == '.')))
cfa658e4
ILT
428 {
429 fprintf (stderr,
430 "test5: unexpected syminfo name got %s expected %s\n",
431 symdata.name, "global");
432 symdata.failed = 1;
433 }
1f96a712
JJ
434 else if (symdata.val != (uintptr_t) &global)
435 {
436 fprintf (stderr,
437 "test5: unexpected syminfo value got %lx expected %lx\n",
438 (unsigned long) symdata.val,
439 (unsigned long) (uintptr_t) &global);
440 symdata.failed = 1;
441 }
442 else if (symdata.size != sizeof (global))
443 {
444 fprintf (stderr,
445 "test5: unexpected syminfo size got %lx expected %lx\n",
446 (unsigned long) symdata.size,
447 (unsigned long) sizeof (global));
448 symdata.failed = 1;
449 }
cfa658e4
ILT
450 }
451
452 printf ("%s: backtrace_syminfo variable\n",
453 symdata.failed ? "FAIL" : "PASS");
454
455 if (symdata.failed)
456 ++failures;
457
458 return failures;
459}
460
65d0b859
ILT
461/* Check that are no files left open. */
462
463static void
464check_open_files (void)
465{
466 int i;
467
468 for (i = 3; i < 10; i++)
469 {
470 if (close (i) == 0)
471 {
472 fprintf (stderr,
473 "ERROR: descriptor %d still open after tests complete\n",
474 i);
475 ++failures;
476 }
477 }
478}
479
eff02e4f
ILT
480/* Run all the tests. */
481
482int
483main (int argc ATTRIBUTE_UNUSED, char **argv)
484{
485 state = backtrace_create_state (argv[0], BACKTRACE_SUPPORTS_THREADS,
486 error_callback_create, NULL);
487
488#if BACKTRACE_SUPPORTED
489 test1 ();
490 test2 ();
491 test3 ();
492 test4 ();
e24afc10 493#if BACKTRACE_SUPPORTS_DATA
cfa658e4 494 test5 ();
e24afc10 495#endif
eff02e4f
ILT
496#endif
497
65d0b859
ILT
498 check_open_files ();
499
eff02e4f
ILT
500 exit (failures ? EXIT_FAILURE : EXIT_SUCCESS);
501}