This is the mail archive of the archer@sourceware.org mailing list for the Archer project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [python] Something rotten in exception cleanup


>>>>> "Paul" == Paul Pluzhnikov <ppluzhnikov@google.com> writes:

Paul> There is something rotten in Python cleanup of exceptions:

Thanks for reporting this.

Paul> It looks like there are cleanup routines, that refer to stack
Paul> locations already popped off.

Paul> I'll try to debug this further, but posting just in case someone
Paul> can spot the problem right away.

I went ahead and looked at it, I hope that doesn't inconvenience you.

The bug is that it is not valid to "return" from inside a TRY_CATCH.
This patch fixes all the instances of this that I could find.  I only
checked python/*.c.

This made the valgrind errors go away for me, using your example.
Could you try it, too?

One more bug that would not have happened in C++ ... :-)

Tom

2008-12-16  Tom Tromey  <tromey@redhat.com>

	* python/python-frame.c (FRAPY_REQUIRE_VALID): Use error, not
	python exception.
	(gdbpy_frames): Don't return inside a TRY_CATCH.
	(gdbpy_current_frame): Likewise.
	(gdbpy_selected_frame): Likewise.
	* python/python.c (gdbpy_parameter): Don't return inside a
	TRY_CATCH.

diff --git a/gdb/python/python-frame.c b/gdb/python/python-frame.c
index e6f2ada..69bb36b 100644
--- a/gdb/python/python-frame.c
+++ b/gdb/python/python-frame.c
@@ -42,14 +42,13 @@ typedef struct {
   int frame_id_is_next;
 } frame_object;
 
-#define FRAPY_REQUIRE_VALID(frame_obj, frame)			      \
-    do {							      \
-      frame = frame_object_to_frame_info (frame_obj);		      \
-      if (frame == NULL)					      \
-        {							      \
-	  PyErr_SetString (PyExc_RuntimeError, "Frame is invalid.");  \
-	  return NULL;						      \
-	}							      \
+/* Require a valid frame.  This must be called inside a TRY_CATCH, or
+   another context in which a gdb exception is allowed.  */
+#define FRAPY_REQUIRE_VALID(frame_obj, frame)		\
+    do {						\
+      frame = frame_object_to_frame_info (frame_obj);	\
+      if (frame == NULL)				\
+	error ("Frame is invalid.");			\
     } while (0)
 
 static PyTypeObject frame_object_type;
@@ -382,7 +381,8 @@ gdbpy_frames (PyObject *self, PyObject *args)
 	  if (frame_obj == NULL)
 	    {
 	      Py_DECREF (list);
-	      return NULL;
+	      list = NULL;
+	      break;
 	    }
 
 	  PyList_Append (list, (PyObject *) frame_obj);
@@ -396,8 +396,13 @@ gdbpy_frames (PyObject *self, PyObject *args)
 			   "%s", except.message);
     }
 
-  tuple = PyList_AsTuple (list);
-  Py_DECREF (list);
+  if (list)
+    {
+      tuple = PyList_AsTuple (list);
+      Py_DECREF (list);
+    }
+  else
+    tuple = NULL;
 
   return tuple;
 }
@@ -413,8 +418,6 @@ gdbpy_current_frame (PyObject *self, PyObject *args)
     {
       frame = get_current_frame ();
       frame_obj = frame_info_to_frame_object (frame);
-      if (frame_obj == NULL)
-	return NULL;
     }
   GDB_PY_HANDLE_EXCEPTION (except);
 
@@ -432,8 +435,6 @@ gdbpy_selected_frame (PyObject *self, PyObject *args)
     {
       frame = get_selected_frame ("No frame is currently selected.");
       frame_obj = frame_info_to_frame_object (frame);
-      if (frame_obj == NULL)
-	return NULL;
     }
   GDB_PY_HANDLE_EXCEPTION (except);
 
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 02e5c61..9f1c8a4 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -228,6 +228,7 @@ gdbpy_parameter (PyObject *self, PyObject *args)
 {
   struct cmd_list_element *alias, *prefix, *cmd;
   char *arg, *newarg;
+  int found = -1;
   volatile struct gdb_exception except;
 
   if (! PyArg_ParseTuple (args, "s", &arg))
@@ -237,15 +238,13 @@ gdbpy_parameter (PyObject *self, PyObject *args)
 
   TRY_CATCH (except, RETURN_MASK_ALL)
     {
-      if (! lookup_cmd_composition (newarg, &alias, &prefix, &cmd))
-	{
-	  xfree (newarg);
-	  return PyErr_Format (PyExc_RuntimeError,
-			       "could not find parameter `%s'", arg);
-	}
+      found = lookup_cmd_composition (newarg, &alias, &prefix, &cmd);
     }
   xfree (newarg);
   GDB_PY_HANDLE_EXCEPTION (except);
+  if (!found)
+    return PyErr_Format (PyExc_RuntimeError,
+			 "could not find parameter `%s'", arg);
 
   if (! cmd->var)
     return PyErr_Format (PyExc_RuntimeError, "`%s' is not a parameter", arg);


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]