libctf: error-handling fixes
authorNick Alcock <nick.alcock@oracle.com>
Fri, 20 Nov 2020 13:34:04 +0000 (13:34 +0000)
committerNick Alcock <nick.alcock@oracle.com>
Fri, 20 Nov 2020 13:34:12 +0000 (13:34 +0000)
libctf/ChangeLog
2020-11-20  Nick Alcock  <nick.alcock@oracle.com>

* ctf-create.c (ctf_dtd_insert): Set ENOMEM on the dict if out of memory.
(ctf_dvd_insert): Likewise.
(ctf_add_function): Report ECTF_RDONLY if this dict is not writable.
* ctf-subr.c (ctf_err_warn): Only debug-dump passed-in warnings if
the passed-in error code is nonzero: the error on the dict for
warnings may relate to a previous error.

libctf/ChangeLog
libctf/ctf-create.c
libctf/ctf-subr.c

index 685c06a01420b6898efd066e1d1cd6bf7f8a36b8..0a8da127616f5ab0d25266473f1de29f264670e7 100644 (file)
@@ -1,3 +1,12 @@
+2020-11-20  Nick Alcock  <nick.alcock@oracle.com>
+
+       * ctf-create.c (ctf_dtd_insert): Set ENOMEM on the dict if out of memory.
+       (ctf_dvd_insert): Likewise.
+       (ctf_add_function): Report ECTF_RDONLY if this dict is not writable.
+       * ctf-subr.c (ctf_err_warn): Only debug-dump passed-in warnings if
+       the passed-in error code is nonzero: the error on the dict for
+       warnings may relate to a previous error.
+
 2020-11-20  Nick Alcock  <nick.alcock@oracle.com>
 
        * ctf-open.c (ctf_getsymsect): New.
index 5fc50a519e933cdad38f95756823d6a6b312e486..c3223a72ac4ba036355ec9b26e2ce7d780a7dab8 100644 (file)
@@ -1257,7 +1257,10 @@ ctf_dtd_insert (ctf_dict_t *fp, ctf_dtdef_t *dtd, int flag, int kind)
   const char *name;
   if (ctf_dynhash_insert (fp->ctf_dthash, (void *) (uintptr_t) dtd->dtd_type,
                          dtd) < 0)
-    return -1;
+    {
+      ctf_set_errno (fp, ENOMEM);
+      return -1;
+    }
 
   if (flag == CTF_ADD_ROOT && dtd->dtd_data.ctt_name
       && (name = ctf_strraw (fp, dtd->dtd_data.ctt_name)) != NULL)
@@ -1268,6 +1271,7 @@ ctf_dtd_insert (ctf_dict_t *fp, ctf_dtdef_t *dtd, int flag, int kind)
        {
          ctf_dynhash_remove (fp->ctf_dthash, (void *) (uintptr_t)
                              dtd->dtd_type);
+         ctf_set_errno (fp, ENOMEM);
          return -1;
        }
     }
@@ -1349,7 +1353,10 @@ int
 ctf_dvd_insert (ctf_dict_t *fp, ctf_dvdef_t *dvd)
 {
   if (ctf_dynhash_insert (fp->ctf_dvhash, dvd->dvd_name, dvd) < 0)
-    return -1;
+    {
+      ctf_set_errno (fp, ENOMEM);
+      return -1;
+    }
   ctf_list_append (&fp->ctf_dvdefs, dvd);
   return 0;
 }
@@ -1721,6 +1728,9 @@ ctf_add_function (ctf_dict_t *fp, uint32_t flag,
   ctf_dict_t *tmp = fp;
   size_t i;
 
+  if (!(fp->ctf_flags & LCTF_RDWR))
+    return (ctf_set_errno (fp, ECTF_RDONLY));
+
   if (ctc == NULL || (ctc->ctc_flags & ~CTF_FUNC_VARARG) != 0
       || (ctc->ctc_argc != 0 && argv == NULL))
     return (ctf_set_errno (fp, EINVAL));
index c902494590c15693a48d64009605034e0f358b0e..a4d445a4523d877358ac3218f9ecf78a9ccfb147 100644 (file)
@@ -225,10 +225,12 @@ ctf_err_warn (ctf_dict_t *fp, int is_warning, int err,
     }
   va_end (alist);
 
-  /* Include the error code only if there is one, and if this is not a warning.
+  /* Include the error code only if there is one; if this is not a warning,
+     only use the error code if it was explicitly passed and is nonzero.
      (Warnings may not have a meaningful error code, since the warning may not
      lead to unwinding up to the user.)  */
-  if (!is_warning && (err != 0 || (fp && ctf_errno (fp) != 0)))
+  if ((!is_warning && (err != 0 || (fp && ctf_errno (fp) != 0)))
+      || (is_warning && err != 0))
     ctf_dprintf ("%s: %s (%s)\n", is_warning ? _("error") : _("warning"),
                 cew->cew_text, err != 0 ? ctf_errmsg (err)
                 : ctf_errmsg (ctf_errno (fp)));