diff options
author | Nick Alcock <nick.alcock@oracle.com> | 2023-04-05 17:21:32 +0100 |
---|---|---|
committer | Nick Alcock <nick.alcock@oracle.com> | 2023-04-08 16:07:17 +0100 |
commit | d7474051e87c5804c2b674c0d3ad78030f0464a7 (patch) | |
tree | 26e0e288d9f536d62807077854efa77a8538cdd6 /libctf/ctf-lookup.c | |
parent | 30a794e9f1db2de9099ed4c494d917d4e86de0fd (diff) | |
download | gdb-d7474051e87c5804c2b674c0d3ad78030f0464a7.zip gdb-d7474051e87c5804c2b674c0d3ad78030f0464a7.tar.gz gdb-d7474051e87c5804c2b674c0d3ad78030f0464a7.tar.bz2 |
libctf: propagate errors from parents correctly
CTF dicts have per-dict errno values: as with other errno values these
are set on error and left unchanged on success. This means that all
errors *must* set the CTF errno: if a call leaves it unchanged, the
caller is apt to find a previous, lingering error and misinterpret
it as the real error.
There are many places in libctf where we carry out operations on parent
dicts as a result of carrying out other user-requested operations on
child dicts (e.g. looking up information on a pointer to a type will
look up the type as well: the pointer might well be in a child and the
type it's a pointer to in the parent). Those operations on the parent
might fail; if they do, the error must be correctly reflected on the
child that the user-visible operation was carried out on. In many
places this was not happening.
So, audit and fix all those places. Add tests for as many of those
cases as possible so they don't regress.
libctf/
* ctf-create.c (ctf_add_slice): Use the original dict.
* ctf-lookup.c (ctf_lookup_variable): Propagate errors.
(ctf_lookup_symbol_idx): Likewise.
* ctf-types.c (ctf_member_next): Likewise.
(ctf_type_resolve_unsliced): Likewise.
(ctf_type_aname): Likewise.
(ctf_member_info): Likewise.
(ctf_type_rvisit): Likewise.
(ctf_func_type_info): Set the error on the right dict.
(ctf_type_encoding): Use the original dict.
* testsuite/libctf-writable/error-propagation.*: New test.
Diffstat (limited to 'libctf/ctf-lookup.c')
-rw-r--r-- | libctf/ctf-lookup.c | 19 |
1 files changed, 17 insertions, 2 deletions
diff --git a/libctf/ctf-lookup.c b/libctf/ctf-lookup.c index 950c0a8..c658491 100644 --- a/libctf/ctf-lookup.c +++ b/libctf/ctf-lookup.c @@ -402,7 +402,13 @@ ctf_lookup_variable (ctf_dict_t *fp, const char *name) if (ent == NULL) { if (fp->ctf_parent != NULL) - return ctf_lookup_variable (fp->ctf_parent, name); + { + ctf_id_t ptype; + + if ((ptype = ctf_lookup_variable (fp->ctf_parent, name)) != CTF_ERR) + return ptype; + return (ctf_set_errno (fp, ctf_errno (fp->ctf_parent))); + } return (ctf_set_errno (fp, ECTF_NOTYPEDAT)); } @@ -626,7 +632,16 @@ ctf_lookup_symbol_idx (ctf_dict_t *fp, const char *symname) try_parent: if (fp->ctf_parent) - return ctf_lookup_symbol_idx (fp->ctf_parent, symname); + { + unsigned long psym; + + if ((psym = ctf_lookup_symbol_idx (fp->ctf_parent, symname)) + != (unsigned long) -1) + return psym; + + ctf_set_errno (fp, ctf_errno (fp->ctf_parent)); + return (unsigned long) -1; + } else { ctf_set_errno (fp, err); |