packaging: add 64bit libs on 32bit build env
[platform/upstream/linaro-glibc.git] / debug / tst-backtrace4.c
1 /* Test backtrace and backtrace_symbols for signal frames.
2    Copyright (C) 2011-2014 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    <http://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 #include <sys/types.h>
25 #include <signal.h>
26 #include <unistd.h>
27
28 #include "tst-backtrace.h"
29
30 static int do_test (void);
31 #define TEST_FUNCTION do_test ()
32 #include "../test-skeleton.c"
33
34 /* The backtrace should include at least handle_signal, a signal
35    trampoline, 3 * fn, and do_test.  */
36 #define NUM_FUNCTIONS 6
37
38 volatile int sig_handled = 0;
39
40 void
41 handle_signal (int signum)
42 {
43   void *addresses[NUM_FUNCTIONS];
44   char **symbols;
45   int n;
46   int i;
47
48   sig_handled = 1;
49
50   /* Get the backtrace addresses.  */
51   n = backtrace (addresses, sizeof (addresses) / sizeof (addresses[0]));
52   printf ("Obtained backtrace with %d functions (but wanted at least %d)\n",
53           n, NUM_FUNCTIONS);
54   /* Check that there are at least six functions.  */
55   if (n < NUM_FUNCTIONS)
56     {
57       FAIL ();
58       /* Only return if we got no symbols at all.  The partial output is
59          still useful for debugging failures.  */
60       if (n <= 0)
61         return;
62     }
63   /* Convert them to symbols.  */
64   symbols = backtrace_symbols (addresses, n);
65   /* Check that symbols were obtained.  */
66   if (symbols == NULL)
67     {
68       FAIL ();
69       return;
70     }
71   for (i = 0; i < n; ++i)
72     printf ("Function %d: %s\n", i, symbols[i]);
73   /* Check that the function names obtained are accurate.  */
74   if (!match (symbols[0], "handle_signal"))
75     FAIL ();
76   /* Do not check name for signal trampoline.  */
77   for (i = 2; i < n - 1; i++)
78     if (!match (symbols[i], "fn"))
79       {
80         FAIL ();
81         return;
82       }
83   /* Symbol names are not available for static functions, so we do not
84      check do_test.  */
85 }
86
87 NO_INLINE int
88 fn (int c)
89 {
90   pid_t parent_pid, child_pid;
91
92   if (c > 0)
93     {
94       fn (c - 1);
95       return x;
96     }
97
98   signal (SIGUSR1, handle_signal);
99   parent_pid = getpid ();
100
101   child_pid = fork ();
102   if (child_pid == (pid_t) -1)
103     abort ();
104   else if (child_pid == 0)
105     {
106       sleep (1);
107       kill (parent_pid, SIGUSR1);
108       _exit (0);
109     }
110
111   /* In the parent.  */
112   while (sig_handled == 0)
113     ;
114
115   return 0;
116 }
117
118 NO_INLINE static int
119 do_test (void)
120 {
121   fn (2);
122   return ret;
123 }