xref: /netbsd-src/external/gpl3/gdb/dist/libctf/testsuite/libctf-writable/error-propagation.c (revision c9055873d0546e63388f027d3d7f85381cde0545)
1*c9055873Schristos /* Make sure that errors are propagated properly from parent dicts to children
2*c9055873Schristos    when errors are encountered in child functions that can recurse to parents.
3*c9055873Schristos 
4*c9055873Schristos    We check specifically a subset of known-buggy functions.
5*c9055873Schristos    Functions that require a buggy linker to expose, or that only fail on
6*c9055873Schristos    assertion-failure-incurring corrupted dicts, are not tested. */
7*c9055873Schristos 
8*c9055873Schristos #include <ctf-api.h>
9*c9055873Schristos #include <stdio.h>
10*c9055873Schristos #include <stdlib.h>
11*c9055873Schristos #include <string.h>
12*c9055873Schristos 
13*c9055873Schristos static const char *desc;
14*c9055873Schristos 
15*c9055873Schristos static void
16*c9055873Schristos check_prop_err (ctf_dict_t *child, ctf_dict_t *parent, int expected)
17*c9055873Schristos {
18*c9055873Schristos   if (ctf_errno (child) == expected)
19*c9055873Schristos     return;
20*c9055873Schristos 
21*c9055873Schristos   if (ctf_errno (parent) == expected)
22*c9055873Schristos     fprintf (stderr, "%s: error propagation failure: error \"%s\" not seen on child, "
23*c9055873Schristos              "but instead on parent\n", desc, ctf_errmsg (ctf_errno (parent)));
24*c9055873Schristos   else
25*c9055873Schristos     fprintf (stderr, "%s: expected error is entirely lost: "
26*c9055873Schristos              "\"%s\" seen on parent, \"%s\" on child\n", desc,
27*c9055873Schristos              ctf_errmsg (ctf_errno (parent)),
28*c9055873Schristos              ctf_errmsg (ctf_errno (child)));
29*c9055873Schristos }
30*c9055873Schristos 
31*c9055873Schristos static void
32*c9055873Schristos no_prop_err (void)
33*c9055873Schristos {
34*c9055873Schristos   fprintf (stderr, "%s: expected error return not observed.\n", desc);
35*c9055873Schristos }
36*c9055873Schristos 
37*c9055873Schristos int main (void)
38*c9055873Schristos {
39*c9055873Schristos   ctf_dict_t *parent;
40*c9055873Schristos   ctf_dict_t *blank;
41*c9055873Schristos   ctf_dict_t *child;
42*c9055873Schristos   ctf_id_t void_id;
43*c9055873Schristos   ctf_id_t base;
44*c9055873Schristos   ctf_id_t slice;
45*c9055873Schristos   ctf_id_t function;
46*c9055873Schristos   ctf_encoding_t long_encoding = { CTF_INT_SIGNED, 0, sizeof (long) };
47*c9055873Schristos   ctf_encoding_t void_encoding = { CTF_INT_SIGNED, 0, 0 };
48*c9055873Schristos   ctf_encoding_t foo;
49*c9055873Schristos   ctf_funcinfo_t fi;
50*c9055873Schristos   ctf_id_t bar;
51*c9055873Schristos   char *funcname;
52*c9055873Schristos   int err;
53*c9055873Schristos 
54*c9055873Schristos   if ((parent = ctf_create (&err)) == NULL
55*c9055873Schristos       || (child = ctf_create (&err)) == NULL
56*c9055873Schristos       || (blank = ctf_create (&err)) == NULL)
57*c9055873Schristos     {
58*c9055873Schristos       fprintf (stderr, "Cannot create dicts: %s\n", ctf_errmsg (err));
59*c9055873Schristos       return 1;
60*c9055873Schristos     }
61*c9055873Schristos 
62*c9055873Schristos   if ((ctf_import (child, parent)) < 0)
63*c9055873Schristos     {
64*c9055873Schristos       fprintf (stderr, "cannot import: %s\n", ctf_errmsg (ctf_errno (child)));
65*c9055873Schristos       return 1;
66*c9055873Schristos     }
67*c9055873Schristos 
68*c9055873Schristos   if ((void_id = ctf_add_integer (parent, CTF_ADD_ROOT, "void", &void_encoding))
69*c9055873Schristos       == CTF_ERR)
70*c9055873Schristos     goto parent_err;
71*c9055873Schristos 
72*c9055873Schristos   if ((base = ctf_add_integer (parent, CTF_ADD_ROOT, "long int", &long_encoding))
73*c9055873Schristos       == CTF_ERR)
74*c9055873Schristos     goto parent_err;
75*c9055873Schristos 
76*c9055873Schristos   foo.cte_format = 0;
77*c9055873Schristos   foo.cte_bits = 4;
78*c9055873Schristos   foo.cte_offset = 4;
79*c9055873Schristos   if ((slice = ctf_add_slice (child, CTF_ADD_ROOT, base, &foo)) == CTF_ERR)
80*c9055873Schristos     goto parent_err;
81*c9055873Schristos 
82*c9055873Schristos   if (ctf_add_variable (parent, "foo", base) < 0)
83*c9055873Schristos     goto child_err;
84*c9055873Schristos 
85*c9055873Schristos   fi.ctc_return = void_id;
86*c9055873Schristos   fi.ctc_argc = 0;
87*c9055873Schristos   fi.ctc_flags = 0;
88*c9055873Schristos   if ((function = ctf_add_function (child, CTF_ADD_ROOT, &fi, NULL)) == CTF_ERR)
89*c9055873Schristos     goto child_err;
90*c9055873Schristos 
91*c9055873Schristos   desc = "func info lookup of non-function";
92*c9055873Schristos   if ((ctf_func_type_info (child, base, &fi)) != CTF_ERR)
93*c9055873Schristos     no_prop_err ();
94*c9055873Schristos   check_prop_err (child, parent, ECTF_NOTFUNC);
95*c9055873Schristos 
96*c9055873Schristos   desc = "func args lookup of non-function";
97*c9055873Schristos   if ((ctf_func_type_args (child, base, 0, &bar)) != CTF_ERR)
98*c9055873Schristos     no_prop_err ();
99*c9055873Schristos   check_prop_err (child, parent, ECTF_NOTFUNC);
100*c9055873Schristos 
101*c9055873Schristos   if ((ctf_import (child, blank)) < 0)
102*c9055873Schristos     {
103*c9055873Schristos       fprintf (stderr, "cannot reimport: %s\n", ctf_errmsg (ctf_errno (child)));
104*c9055873Schristos       return 1;
105*c9055873Schristos     }
106*c9055873Schristos 
107*c9055873Schristos   /* This is testing ctf_type_resolve_unsliced(), which is called by the enum
108*c9055873Schristos      functions (which are not themselves buggy).  This typea isn't an enum, but
109*c9055873Schristos      that's OK: we're after an error, after all, and the type we're slicing is
110*c9055873Schristos      not visible any longer, so nothing can tell it's not an enum.  */
111*c9055873Schristos 
112*c9055873Schristos   desc = "child slice resolution";
113*c9055873Schristos   if ((ctf_enum_value (child, slice, "foo", NULL)) != CTF_ERR)
114*c9055873Schristos     no_prop_err ();
115*c9055873Schristos   check_prop_err (child, parent, ECTF_BADID);
116*c9055873Schristos 
117*c9055873Schristos   desc = "child slice encoding lookup";
118*c9055873Schristos   if ((ctf_type_encoding (child, slice, &foo)) != CTF_ERR)
119*c9055873Schristos     no_prop_err ();
120*c9055873Schristos   check_prop_err (child, parent, ECTF_BADID);
121*c9055873Schristos 
122*c9055873Schristos   desc = "func info lookup of non-function";
123*c9055873Schristos   if ((ctf_func_type_info (child, base, &fi)) != CTF_ERR)
124*c9055873Schristos     no_prop_err ();
125*c9055873Schristos   check_prop_err (child, parent, ECTF_BADID);
126*c9055873Schristos 
127*c9055873Schristos   desc = "func args lookup of non-function";
128*c9055873Schristos   if ((ctf_func_type_args (child, base, 0, &bar)) != CTF_ERR)
129*c9055873Schristos     no_prop_err ();
130*c9055873Schristos   check_prop_err (child, parent, ECTF_BADID);
131*c9055873Schristos 
132*c9055873Schristos   desc = "child slice addition";
133*c9055873Schristos   if ((slice = ctf_add_slice (child, CTF_ADD_ROOT, base, &foo)) != CTF_ERR)
134*c9055873Schristos     no_prop_err ();
135*c9055873Schristos   check_prop_err (child, parent, ECTF_BADID);
136*c9055873Schristos 
137*c9055873Schristos   desc = "variable lookup";
138*c9055873Schristos   if (ctf_lookup_variable (child, "foo") != CTF_ERR)
139*c9055873Schristos     no_prop_err ();
140*c9055873Schristos   check_prop_err (child, parent, ECTF_NOTYPEDAT);
141*c9055873Schristos 
142*c9055873Schristos   desc = "function lookup via ctf_type_aname";
143*c9055873Schristos   if ((funcname = ctf_type_aname (child, function)) != NULL)
144*c9055873Schristos     {
145*c9055873Schristos       no_prop_err ();
146*c9055873Schristos       free (funcname);
147*c9055873Schristos     }
148*c9055873Schristos   check_prop_err (child, parent, ECTF_BADID);
149*c9055873Schristos 
150*c9055873Schristos   ctf_dict_close (child);
151*c9055873Schristos   ctf_dict_close (parent);
152*c9055873Schristos   ctf_dict_close (blank);
153*c9055873Schristos   fprintf (stderr, "All done.\n");
154*c9055873Schristos   return 0;
155*c9055873Schristos 
156*c9055873Schristos  parent_err:
157*c9055873Schristos   fprintf (stderr, "cannot populate parent: %s\n", ctf_errmsg (ctf_errno (parent)));
158*c9055873Schristos   return 1;
159*c9055873Schristos 
160*c9055873Schristos  child_err:
161*c9055873Schristos   fprintf (stderr, "cannot populate child: %s\n", ctf_errmsg (ctf_errno (parent)));
162*c9055873Schristos   return 1;
163*c9055873Schristos 
164*c9055873Schristos }
165