[python] [patch] PR 12174 (preserve gdb.GdbError behaviour)

Phil Muldoon pmuldoon@redhat.com
Mon Apr 11 14:40:00 GMT 2011


In the case of gdb.execute, gdb.GdbErrors were being converted to GDB
errors and back again to a Runtime Exception.  This is not correct as
gdb.GdbErrors are meant to indicate small, ignorable errors.  I wrote
this patch to identify when a GDB exception is raised from a
gdb.GdbError and print accordingly.

I was unsure if I should call print_exception in gdb.execute or whether
just to let the Python exception propagate.  The latter raises a stack
trace which is not what we want to with gdb.GdbErrors.  Anyway, We can
easily do either.


What do you think?

Cheers

Phil

--

2011-04-11  Phil Muldoon  <pmuldoon@redhat.com>

	* exceptions.h: Add PYTHON_GDB_ERROR.
        python/py-cmd.c (cmdpy_function): Use throw_error over
        error. Use PYTHON_GDB_ERROR exception type.
        python/py-function.c (fnpy_call): Likewise.
        python/py-utils.c (gdbpy_convert_exception): Account for new
        exception type.
        python/python.c (execute_gdb_command): If exception class is
        PYTHON_GDB_ERROR just print it.

2011-04-11  Phil Muldoon  <pmuldoon@redhat.com>

	* gdb.python.py-cmd.exp: Add gdb.execute and gdb.GdbError tests.
	* gdb.python.py-function.exp: Likewise.
--

diff --git a/gdb/exceptions.h b/gdb/exceptions.h
index c1bc605..b31e10d 100644
--- a/gdb/exceptions.h
+++ b/gdb/exceptions.h
@@ -85,6 +85,11 @@ enum errors {
      traceframe.  */
   NOT_AVAILABLE_ERROR,
 
+  /* An exception that can be identified as created from a Python
+     scripted error.  This exception is used when a Python
+     gdb.GdbError is detected and converted to an a GDB Exception.  */
+  PYTHON_GDB_ERROR,
+
   /* Add more errors here.  */
   NR_ERRORS
 };
diff --git a/gdb/python/py-cmd.c b/gdb/python/py-cmd.c
index c0e3291..cd33f51 100644
--- a/gdb/python/py-cmd.c
+++ b/gdb/python/py-cmd.c
@@ -188,16 +188,16 @@ cmdpy_function (struct cmd_list_element *command, char *args, int from_tty)
 	  PyErr_Restore (ptype, pvalue, ptraceback);
 	  gdbpy_print_stack ();
 	  if (msg != NULL && *msg != '\0')
-	    error (_("Error occurred in Python command: %s"), msg);
+	    throw_error (PYTHON_GDB_ERROR, _("Error occurred in Python command: %s"), msg);
 	  else
-	    error (_("Error occurred in Python command."));
+	    throw_error (PYTHON_GDB_ERROR, _("Error occurred in Python command."));
 	}
       else
 	{
 	  Py_XDECREF (ptype);
 	  Py_XDECREF (pvalue);
 	  Py_XDECREF (ptraceback);
-	  error ("%s", msg);
+	  throw_error (PYTHON_GDB_ERROR, "%s", msg);
 	}
     }
 
diff --git a/gdb/python/py-function.c b/gdb/python/py-function.c
index 0c3e6f2..65b579f 100644
--- a/gdb/python/py-function.c
+++ b/gdb/python/py-function.c
@@ -116,17 +116,19 @@ fnpy_call (struct gdbarch *gdbarch, const struct language_defn *language,
 	  PyErr_Restore (ptype, pvalue, ptraceback);
 	  gdbpy_print_stack ();
 	  if (msg != NULL && *msg != '\0')
-	    error (_("Error occurred in Python convenience function: %s"),
-		   msg);
+	    throw_error (PYTHON_GDB_ERROR,
+			 _("Error occurred in Python convenience function: %s"),
+			 msg);
 	  else
-	    error (_("Error occurred in Python convenience function."));
+	    throw_error (PYTHON_GDB_ERROR,
+			 _("Error occurred in Python convenience function."));
 	}
       else
 	{
 	  Py_XDECREF (ptype);
 	  Py_XDECREF (pvalue);
 	  Py_XDECREF (ptraceback);
-	  error ("%s", msg);
+	  throw_error (PYTHON_GDB_ERROR, "%s", msg);
 	}
     }
 
diff --git a/gdb/python/py-utils.c b/gdb/python/py-utils.c
index 601bcb0..5d076d2 100644
--- a/gdb/python/py-utils.c
+++ b/gdb/python/py-utils.c
@@ -286,6 +286,8 @@ gdbpy_convert_exception (struct gdb_exception exception)
     exc_class = PyExc_KeyboardInterrupt;
   else if (exception.error == MEMORY_ERROR)
     exc_class = gdbpy_gdb_memory_error;
+  else if (exception.error == PYTHON_GDB_ERROR)
+    exc_class = gdbpy_gdberror_exc;
   else
     exc_class = gdbpy_gdb_error;
 
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 8a7bc66..2ea6198 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -387,7 +387,13 @@ execute_gdb_command (PyObject *self, PyObject *args, PyObject *kw)
 
       do_cleanups (cleanup);
     }
-  GDB_PY_HANDLE_EXCEPTION (except);
+  if ((except.reason < 0) && (except.error == PYTHON_GDB_ERROR))
+    {
+      exception_print (gdb_stderr, except);
+      Py_RETURN_NONE;
+    }
+  else
+    GDB_PY_HANDLE_EXCEPTION (except);
 
   /* Do any commands attached to breakpoint we stopped at.  */
   bpstat_do_actions ();
diff --git a/gdb/testsuite/gdb.python/py-cmd.exp b/gdb/testsuite/gdb.python/py-cmd.exp
index e4706cd..827afb0 100644
--- a/gdb/testsuite/gdb.python/py-cmd.exp
+++ b/gdb/testsuite/gdb.python/py-cmd.exp
@@ -125,6 +125,11 @@ gdb_py_test_multiple "input command to throw error" \
 
 gdb_test "test_error_cmd ugh" "you lose!" "call error command"
 
+# Test that in the case of commands executed via "gdb.execute" that
+# the Python exception is not converted to a RuntimeError.
+gdb_test "python gdb.execute(\"test_error_cmd ugh\")" \
+    "you lose!" "call error command from gdb.execute"
+
 # Test gdb.string_to_argv.
 
 gdb_test "python print gdb.string_to_argv (\"1 2 3\")" \
diff --git a/gdb/testsuite/gdb.python/py-function.exp b/gdb/testsuite/gdb.python/py-function.exp
index dfccdff..b66a055 100644
--- a/gdb/testsuite/gdb.python/py-function.exp
+++ b/gdb/testsuite/gdb.python/py-function.exp
@@ -83,6 +83,10 @@ gdb_py_test_multiple "Test GDBError" \
 gdb_test "print \$gdberror()" "This is a GdbError.*" \
     "Test GdbError.  There should not be a stack trace"
 
+gdb_test "python gdb.execute(\"print \$gdberror()\")" \
+    "This is a GdbError.*" \
+    "Test GdbError from gdb.execute. There should not be a stack trace"
+
 gdb_py_test_multiple "Test Normal Error" \
   "python" "" \
   "class NormalError(gdb.Function):" "" \



More information about the Gdb-patches mailing list