Consolidate gdb.GdbError handling
authorTom Tromey <tom@tromey.com>
Sat, 15 Sep 2018 06:57:12 +0000 (00:57 -0600)
committerTom Tromey <tom@tromey.com>
Mon, 24 Sep 2018 05:15:12 +0000 (23:15 -0600)
I noticed two nearly identical copies of the same code for handling
gdb.GdbError.  The only differences were in some error messages.
These differences didn't seem very important, so this patch pulls the
code out into a new function.

2018-09-23  Tom Tromey  <tom@tromey.com>

* python/py-function.c (fnpy_call): Use gdbpy_handle_exception.
* python/py-cmd.c (cmdpy_function): Use gdbpy_handle_exception.
* python/python-internal.h (gdbpy_handle_exception): Declare.
* python/py-utils.c (gdbpy_handle_exception): New function.

gdb/ChangeLog
gdb/python/py-cmd.c
gdb/python/py-function.c
gdb/python/py-utils.c
gdb/python/python-internal.h

index f887159d221ee15ee88f42b2b1c5a417433cd350..cbbd146fc94a812cca1a16b19ba0113930e56899 100644 (file)
@@ -1,3 +1,10 @@
+2018-09-23  Tom Tromey  <tom@tromey.com>
+
+       * python/py-function.c (fnpy_call): Use gdbpy_handle_exception.
+       * python/py-cmd.c (cmdpy_function): Use gdbpy_handle_exception.
+       * python/python-internal.h (gdbpy_handle_exception): Declare.
+       * python/py-utils.c (gdbpy_handle_exception): New function.
+
 2018-09-23  Tom Tromey  <tom@tromey.com>
 
        PR python/17284:
index 27c4689413a61fb64e7a0826e7d87480c9f224aa..e7eb66f515c09bfb025c5e45a3f0f8d6b0cad2ef 100644 (file)
@@ -145,53 +145,7 @@ cmdpy_function (struct cmd_list_element *command,
                                                  NULL));
 
   if (result == NULL)
-    {
-      PyObject *ptype, *pvalue, *ptraceback;
-
-      PyErr_Fetch (&ptype, &pvalue, &ptraceback);
-
-      /* Try to fetch an error message contained within ptype, pvalue.
-        When fetching the error message we need to make our own copy,
-        we no longer own ptype, pvalue after the call to PyErr_Restore.  */
-
-      gdb::unique_xmalloc_ptr<char>
-       msg (gdbpy_exception_to_string (ptype, pvalue));
-
-      if (msg == NULL)
-       {
-         /* An error occurred computing the string representation of the
-            error message.  This is rare, but we should inform the user.  */
-         printf_filtered (_("An error occurred in a Python command\n"
-                            "and then another occurred computing the "
-                            "error message.\n"));
-         gdbpy_print_stack ();
-       }
-
-      /* Don't print the stack for gdb.GdbError exceptions.
-        It is generally used to flag user errors.
-
-        We also don't want to print "Error occurred in Python command"
-        for user errors.  However, a missing message for gdb.GdbError
-        exceptions is arguably a bug, so we flag it as such.  */
-
-      if (! PyErr_GivenExceptionMatches (ptype, gdbpy_gdberror_exc)
-         || msg == NULL || *msg == '\0')
-       {
-         PyErr_Restore (ptype, pvalue, ptraceback);
-         gdbpy_print_stack ();
-         if (msg != NULL && *msg != '\0')
-           error (_("Error occurred in Python command: %s"), msg.get ());
-         else
-           error (_("Error occurred in Python command."));
-       }
-      else
-       {
-         Py_XDECREF (ptype);
-         Py_XDECREF (pvalue);
-         Py_XDECREF (ptraceback);
-         error ("%s", msg.get ());
-       }
-    }
+    gdbpy_handle_exception ();
 }
 
 /* Helper function for the Python command completers (both "pure"
index c4612316df6f44d2552c2432d6c1a4ec4547360f..1900f0ff0c0fde4c432b1e829887b6a945b9e877 100644 (file)
@@ -83,56 +83,7 @@ fnpy_call (struct gdbarch *gdbarch, const struct language_defn *language,
     }
 
   if (result == NULL)
-    {
-      PyObject *ptype, *pvalue, *ptraceback;
-
-      PyErr_Fetch (&ptype, &pvalue, &ptraceback);
-
-      /* Try to fetch an error message contained within ptype, pvalue.
-        When fetching the error message we need to make our own copy,
-        we no longer own ptype, pvalue after the call to PyErr_Restore.  */
-
-      gdb::unique_xmalloc_ptr<char>
-       msg (gdbpy_exception_to_string (ptype, pvalue));
-
-      if (msg == NULL)
-       {
-         /* An error occurred computing the string representation of the
-            error message.  This is rare, but we should inform the user.  */
-
-         printf_filtered (_("An error occurred in a Python "
-                            "convenience function\n"
-                            "and then another occurred computing the "
-                            "error message.\n"));
-         gdbpy_print_stack ();
-       }
-
-      /* Don't print the stack for gdb.GdbError exceptions.
-        It is generally used to flag user errors.
-
-        We also don't want to print "Error occurred in Python command"
-        for user errors.  However, a missing message for gdb.GdbError
-        exceptions is arguably a bug, so we flag it as such.  */
-
-      if (!PyErr_GivenExceptionMatches (ptype, gdbpy_gdberror_exc)
-         || msg == NULL || *msg == '\0')
-       {
-         PyErr_Restore (ptype, pvalue, ptraceback);
-         gdbpy_print_stack ();
-         if (msg != NULL && *msg != '\0')
-           error (_("Error occurred in Python convenience function: %s"),
-                  msg.get ());
-         else
-           error (_("Error occurred in Python convenience function."));
-       }
-      else
-       {
-         Py_XDECREF (ptype);
-         Py_XDECREF (pvalue);
-         Py_XDECREF (ptraceback);
-         error ("%s", msg.get ());
-       }
-    }
+    gdbpy_handle_exception ();
 
   value = convert_value_from_python (result.get ());
   if (value == NULL)
index 01fd6ade8d540ade977509f5722ec991a362bf80..6ef0d7efd39ea14a90b82f057ac1f3b9640a9983 100644 (file)
@@ -384,3 +384,59 @@ gdb_pymodule_addobject (PyObject *module, const char *name, PyObject *object)
     Py_DECREF (object);
   return result;
 }
+
+/* Handle a Python exception when the special gdb.GdbError treatment
+   is desired.  This should only be called when an exception is set.
+   If the exception is a gdb.GdbError, throw a gdb exception with the
+   exception text.  For other exceptions, print the Python stack and
+   then throw a gdb exception.  */
+
+void
+gdbpy_handle_exception ()
+{
+  PyObject *ptype, *pvalue, *ptraceback;
+
+  PyErr_Fetch (&ptype, &pvalue, &ptraceback);
+
+  /* Try to fetch an error message contained within ptype, pvalue.
+     When fetching the error message we need to make our own copy,
+     we no longer own ptype, pvalue after the call to PyErr_Restore.  */
+
+  gdb::unique_xmalloc_ptr<char>
+    msg (gdbpy_exception_to_string (ptype, pvalue));
+
+  if (msg == NULL)
+    {
+      /* An error occurred computing the string representation of the
+        error message.  This is rare, but we should inform the user.  */
+      printf_filtered (_("An error occurred in Python "
+                        "and then another occurred computing the "
+                        "error message.\n"));
+      gdbpy_print_stack ();
+    }
+
+  /* Don't print the stack for gdb.GdbError exceptions.
+     It is generally used to flag user errors.
+
+     We also don't want to print "Error occurred in Python command"
+     for user errors.  However, a missing message for gdb.GdbError
+     exceptions is arguably a bug, so we flag it as such.  */
+
+  if (! PyErr_GivenExceptionMatches (ptype, gdbpy_gdberror_exc)
+      || msg == NULL || *msg == '\0')
+    {
+      PyErr_Restore (ptype, pvalue, ptraceback);
+      gdbpy_print_stack ();
+      if (msg != NULL && *msg != '\0')
+       error (_("Error occurred in Python: %s"), msg.get ());
+      else
+       error (_("Error occurred in Python."));
+    }
+  else
+    {
+      Py_XDECREF (ptype);
+      Py_XDECREF (pvalue);
+      Py_XDECREF (ptraceback);
+      error ("%s", msg.get ());
+    }
+}
index e32502d0367cc7436b250c6f0f40595aba1e007a..1812abb5b7b57f377887937a6904df0fe70f6555 100644 (file)
@@ -654,6 +654,7 @@ extern const struct language_defn *python_language;
 
 int gdbpy_print_python_errors_p (void);
 void gdbpy_print_stack (void);
+void gdbpy_handle_exception () ATTRIBUTE_NORETURN;
 
 PyObject *python_string_to_unicode (PyObject *obj);
 gdb::unique_xmalloc_ptr<char> unicode_to_target_string (PyObject *unicode_str);