1 /* Test backtrace and backtrace_symbols.
2    Copyright (C) 2009-2022 Free Software Foundation, Inc.
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 <execinfo.h>
20 #include <search.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <string.h>
24 
25 #include "tst-backtrace.h"
26 
27 /* The backtrace should include at least f1, f2, f3, and do_test.  */
28 #define NUM_FUNCTIONS 4
29 
30 NO_INLINE void
fn1(void)31 fn1 (void)
32 {
33   void *addresses[NUM_FUNCTIONS];
34   char **symbols;
35   int n;
36   int i;
37 
38   /* Get the backtrace addresses.  */
39   n = backtrace (addresses, sizeof (addresses) / sizeof (addresses[0]));
40   printf ("Obtained backtrace with %d functions\n", n);
41   /*  Check that there are at least four functions.  */
42   if (n < NUM_FUNCTIONS)
43     {
44       FAIL ();
45       return;
46     }
47   /* Convert them to symbols.  */
48   symbols = backtrace_symbols (addresses, n);
49   /* Check that symbols were obtained.  */
50   if (symbols == NULL)
51     {
52       FAIL ();
53       return;
54     }
55   for (i = 0; i < n; ++i)
56     printf ("Function %d: %s\n", i, symbols[i]);
57   /* Check that the function names obtained are accurate.  */
58   if (!match (symbols[0], "fn1"))
59     {
60       FAIL ();
61       return;
62     }
63   /* Symbol names are not available for static functions, so we do not
64      check f2.  */
65   if (!match (symbols[2], "fn3"))
66     {
67       FAIL ();
68       return;
69     }
70   /* Symbol names are not available for static functions, so we do not
71      check do_test.  */
72 }
73 
74 NO_INLINE int
fn2(void)75 fn2 (void)
76 {
77   fn1 ();
78   /* Prevent tail calls.  */
79   return x;
80 }
81 
82 NO_INLINE int
fn3(void)83 fn3 (void)
84 {
85   fn2();
86   /* Prevent tail calls.  */
87   return x;
88 }
89 
90 NO_INLINE int
do_test(void)91 do_test (void)
92 {
93   /* Test BZ #18084.  */
94   void *buffer[1];
95 
96   if (backtrace (buffer, 0) != 0)
97     FAIL ();
98 
99   fn3 ();
100   return ret;
101 }
102 
103 #include <support/test-driver.c>
104