1 /* testlib.c -- test functions for libbacktrace library
2    Copyright (C) 2012-2018 Free Software Foundation, Inc.
3    Written by Ian Lance Taylor, Google.
4 
5 Redistribution and use in source and binary forms, with or without
6 modification, are permitted provided that the following conditions are
7 met:
8 
9     (1) Redistributions of source code must retain the above copyright
10     notice, this list of conditions and the following disclaimer.
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
15     distribution.
16 
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 
21 THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22 IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
23 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
24 DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
25 INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
26 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
27 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
29 STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
30 IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 POSSIBILITY OF SUCH DAMAGE.  */
32 
33 #include <assert.h>
34 #include <stdio.h>
35 #include <stdlib.h>
36 #include <string.h>
37 
38 #include "filenames.h"
39 
40 #include "backtrace.h"
41 
42 #include "testlib.h"
43 
44 /* The backtrace state.  */
45 
46 void *state;
47 
48 /* The number of failures.  */
49 
50 int failures;
51 
52 /* Return the base name in a path.  */
53 
54 const char *
base(const char * p)55 base (const char *p)
56 {
57   const char *last;
58   const char *s;
59 
60   last = NULL;
61   for (s = p; *s != '\0'; ++s)
62     {
63       if (IS_DIR_SEPARATOR (*s))
64 	last = s + 1;
65     }
66   return last != NULL ? last : p;
67 }
68 
69 /* Check an entry in a struct info array.  */
70 
71 void
check(const char * name,int index,const struct info * all,int want_lineno,const char * want_function,const char * want_file,int * failed)72 check (const char *name, int index, const struct info *all, int want_lineno,
73        const char *want_function, const char *want_file, int *failed)
74 {
75   if (*failed)
76     return;
77   if (all[index].filename == NULL || all[index].function == NULL)
78     {
79       fprintf (stderr, "%s: [%d]: missing file name or function name\n",
80 	       name, index);
81       *failed = 1;
82       return;
83     }
84   if (strcmp (base (all[index].filename), want_file) != 0)
85     {
86       fprintf (stderr, "%s: [%d]: got %s expected %s\n", name, index,
87 	       all[index].filename, want_file);
88       *failed = 1;
89     }
90   if (all[index].lineno != want_lineno)
91     {
92       fprintf (stderr, "%s: [%d]: got %d expected %d\n", name, index,
93 	       all[index].lineno, want_lineno);
94       *failed = 1;
95     }
96   if (strcmp (all[index].function, want_function) != 0)
97     {
98       fprintf (stderr, "%s: [%d]: got %s expected %s\n", name, index,
99 	       all[index].function, want_function);
100       *failed = 1;
101     }
102 }
103 
104 /* The backtrace callback function.  */
105 
106 int
callback_one(void * vdata,uintptr_t pc ATTRIBUTE_UNUSED,const char * filename,int lineno,const char * function)107 callback_one (void *vdata, uintptr_t pc ATTRIBUTE_UNUSED,
108 	      const char *filename, int lineno, const char *function)
109 {
110   struct bdata *data = (struct bdata *) vdata;
111   struct info *p;
112 
113   if (data->index >= data->max)
114     {
115       fprintf (stderr, "callback_one: callback called too many times\n");
116       data->failed = 1;
117       return 1;
118     }
119 
120   p = &data->all[data->index];
121   if (filename == NULL)
122     p->filename = NULL;
123   else
124     {
125       p->filename = strdup (filename);
126       assert (p->filename != NULL);
127     }
128   p->lineno = lineno;
129   if (function == NULL)
130     p->function = NULL;
131   else
132     {
133       p->function = strdup (function);
134       assert (p->function != NULL);
135     }
136   ++data->index;
137 
138   return 0;
139 }
140 
141 /* An error callback passed to backtrace.  */
142 
143 void
error_callback_one(void * vdata,const char * msg,int errnum)144 error_callback_one (void *vdata, const char *msg, int errnum)
145 {
146   struct bdata *data = (struct bdata *) vdata;
147 
148   fprintf (stderr, "%s", msg);
149   if (errnum > 0)
150     fprintf (stderr, ": %s", strerror (errnum));
151   fprintf (stderr, "\n");
152   data->failed = 1;
153 }
154 
155 /* The backtrace_simple callback function.  */
156 
157 int
callback_two(void * vdata,uintptr_t pc)158 callback_two (void *vdata, uintptr_t pc)
159 {
160   struct sdata *data = (struct sdata *) vdata;
161 
162   if (data->index >= data->max)
163     {
164       fprintf (stderr, "callback_two: callback called too many times\n");
165       data->failed = 1;
166       return 1;
167     }
168 
169   data->addrs[data->index] = pc;
170   ++data->index;
171 
172   return 0;
173 }
174 
175 /* An error callback passed to backtrace_simple.  */
176 
177 void
error_callback_two(void * vdata,const char * msg,int errnum)178 error_callback_two (void *vdata, const char *msg, int errnum)
179 {
180   struct sdata *data = (struct sdata *) vdata;
181 
182   fprintf (stderr, "%s", msg);
183   if (errnum > 0)
184     fprintf (stderr, ": %s", strerror (errnum));
185   fprintf (stderr, "\n");
186   data->failed = 1;
187 }
188 
189 /* The backtrace_syminfo callback function.  */
190 
191 void
callback_three(void * vdata,uintptr_t pc ATTRIBUTE_UNUSED,const char * symname,uintptr_t symval,uintptr_t symsize)192 callback_three (void *vdata, uintptr_t pc ATTRIBUTE_UNUSED,
193 		const char *symname, uintptr_t symval,
194 		uintptr_t symsize)
195 {
196   struct symdata *data = (struct symdata *) vdata;
197 
198   if (symname == NULL)
199     data->name = NULL;
200   else
201     {
202       data->name = strdup (symname);
203       assert (data->name != NULL);
204     }
205   data->val = symval;
206   data->size = symsize;
207 }
208 
209 /* The backtrace_syminfo error callback function.  */
210 
211 void
error_callback_three(void * vdata,const char * msg,int errnum)212 error_callback_three (void *vdata, const char *msg, int errnum)
213 {
214   struct symdata *data = (struct symdata *) vdata;
215 
216   fprintf (stderr, "%s", msg);
217   if (errnum > 0)
218     fprintf (stderr, ": %s", strerror (errnum));
219   fprintf (stderr, "\n");
220   data->failed = 1;
221 }
222 
223 /* The backtrace_create_state error callback function.  */
224 
225 void
error_callback_create(void * data ATTRIBUTE_UNUSED,const char * msg,int errnum)226 error_callback_create (void *data ATTRIBUTE_UNUSED, const char *msg,
227                        int errnum)
228 {
229   fprintf (stderr, "%s", msg);
230   if (errnum > 0)
231     fprintf (stderr, ": %s", strerror (errnum));
232   fprintf (stderr, "\n");
233   exit (EXIT_FAILURE);
234 }
235