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