public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM]  archer-pmuldoon-python-backtrace: Refactor frame argument printing.  Roughly implement print local variables.
@ 2012-03-27 16:39 pmuldoon
  0 siblings, 0 replies; only message in thread
From: pmuldoon @ 2012-03-27 16:39 UTC (permalink / raw)
  To: archer-commits

The branch, archer-pmuldoon-python-backtrace has been updated
       via  6a48d614cf35d16e6f4ac3b7cacba5682d9c445e (commit)
      from  91c892b685cdcea5a1a23f358b322517b22ebc51 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email.

- Log -----------------------------------------------------------------
commit 6a48d614cf35d16e6f4ac3b7cacba5682d9c445e
Author: Phil Muldoon <pmuldoon@redhat.com>
Date:   Tue Mar 27 17:38:55 2012 +0100

    Refactor frame argument printing.  Roughly implement print local
    variables.

-----------------------------------------------------------------------

Summary of changes:
 gdb/python/py-framefilter.c                 |  436 ++++++++++++++++++---------
 gdb/python/python.h                         |    5 +-
 gdb/stack.c                                 |   17 +-
 gdb/testsuite/gdb.python/py-framefilter.c   |   17 +
 gdb/testsuite/gdb.python/py-framefilter.exp |    1 +
 gdb/testsuite/gdb.python/py-framefilter.py  |   39 +++
 6 files changed, 369 insertions(+), 146 deletions(-)

First 500 lines of diff:
diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c
index 9a96bae..f5ce701 100644
--- a/gdb/python/py-framefilter.c
+++ b/gdb/python/py-framefilter.c
@@ -246,7 +246,279 @@ find_frame_filter (PyObject *frame, int print_level,
 }
 
 static int
-print_frame (PyObject *filter,
+py_print_locals (PyObject *filter,
+		 struct value_print_options opts)
+{
+  int indent = 4;
+  struct ui_stream *stb;
+  struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
+
+  if (PyObject_HasAttrString (filter, "frame_locals"))
+    {
+      PyObject *result = PyObject_CallMethod (filter, "frame_locals", NULL);
+      volatile struct gdb_exception except;
+      const struct language_defn *language;
+
+      if (result)
+	{
+	  Py_ssize_t size, list_index;
+
+	  make_cleanup_py_decref (result);
+
+	  if (! PyList_Check (result))
+	    {
+	      PyErr_SetString (PyExc_RuntimeError,
+			       _("frame_locals must return a Python list."));
+	      goto locals_error;
+	    }
+
+	  size = PyList_Size (result);
+
+	  if (size > 0)
+	    {
+	      for (list_index = 0; list_index < size; list_index++)
+		{
+		  PyObject *sym_tuple, *sym, *value;
+		  char *sym_name;
+		  struct value *val;
+		  struct symbol *symbol;
+
+		  sym_tuple = PyList_GetItem (result, list_index);
+		  if (! sym_tuple)
+		    goto locals_error;
+
+		  if (! PyTuple_Check (sym_tuple)
+		      && PyTuple_Size (sym_tuple) != 2)
+		    {
+		      PyErr_SetString (PyExc_RuntimeError,
+				       _("frame_locals list must contain a Python tuple."));
+		      goto locals_error;
+		    }
+
+		  /* Each element in the locals arguments list should be a
+		     tuple containing two elements.  The local name,
+		     which can be a string or a gdb.Symbol, and the
+		     value.  */
+
+		  /* Name.  */
+		  sym = PyTuple_GetItem (sym_tuple, 0);
+		  if (! sym)
+		      goto locals_error;
+
+		  /* Value.  */
+		  value = PyTuple_GetItem (sym_tuple, 1);
+		  if (! value)
+		    goto locals_error;
+
+		  /* For arg name, the user can return a symbol or a
+		     string.  */
+		  if (PyString_Check (sym))
+		    {
+		      sym_name = python_string_to_host_string (sym);
+		      language = current_language;
+		      if (! sym_name)
+			goto locals_error;
+		    }
+		  else
+		    {
+		      symbol = symbol_object_to_symbol (sym);
+		      sym_name = xstrdup (SYMBOL_PRINT_NAME (symbol));
+
+		      if (language_mode == language_mode_auto)
+			language = language_def (SYMBOL_LANGUAGE (symbol));
+		      else
+			language = current_language;
+		    }
+
+		  fprintf_filtered (gdb_stdout, "%s%s = ",
+				    n_spaces (2 * indent), sym_name);
+
+		  xfree (sym_name);
+		  val = value_object_to_value (value);
+		  if (! val)
+		    {
+		      PyErr_SetString (PyExc_RuntimeError,
+				       _("Invalid value in frame."));
+
+		      goto locals_error;
+		    }
+
+		  TRY_CATCH (except, RETURN_MASK_ERROR)
+		    {
+		      opts.deref_ref = 1;
+		      common_val_print (val, gdb_stdout, indent, &opts, language);
+		    }
+		  if (except.reason < 0)
+		    {
+		      PyErr_SetString (PyExc_RuntimeError,
+				       except.message);
+		      goto locals_error;
+		    }
+		  fprintf_filtered (gdb_stdout, "\n");
+
+		  gdb_flush (gdb_stdout);
+		}
+	    }
+	}
+      else
+	goto locals_error;
+    }
+
+  do_cleanups (old_chain);
+  return 1;
+
+ locals_error:
+  do_cleanups (old_chain);
+  return 0;
+}
+
+static int
+py_print_args (PyObject *filter,
+	    struct ui_out *out,
+	    struct value_print_options opts,
+	    const char *print_args_type)
+{
+  struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
+  PyObject *result = NULL;
+  struct ui_stream *stb = NULL;
+
+  /* Frame arguments.  */
+  annotate_frame_args ();
+  ui_out_text (out, " (");
+
+  if (PyObject_HasAttrString (filter, "frame_args"))
+    {
+      PyObject *result = PyObject_CallMethod (filter, "frame_args", NULL);
+      volatile struct gdb_exception except;
+      const struct language_defn *language;
+
+      result = PyObject_CallMethod (filter, "frame_args", NULL);
+
+      if (result)
+	{
+	  Py_ssize_t size, list_index;
+
+	  make_cleanup_py_decref (result);
+	  stb = ui_out_stream_new (out);
+	  make_cleanup_ui_out_stream_delete (stb);
+
+	  if (! PyList_Check (result))
+	    {
+	      PyErr_SetString (PyExc_RuntimeError,
+			       _("frame_args must return a Python list."));
+	      goto args_error;
+	    }
+
+	  size = PyList_Size (result);
+
+	  if (size > 0)
+	    {
+	      for (list_index = 0; list_index < size; list_index++)
+		{
+		  PyObject *sym_tuple, *sym, *value;
+		  const char *sym_name;
+		  struct value *val;
+		  struct symbol *symbol;
+
+		  sym_tuple = PyList_GetItem (result, list_index);
+		  if (! sym_tuple)
+		    goto args_error;
+
+		  if (! PyTuple_Check (sym_tuple)
+		      && PyTuple_Size (sym_tuple) != 2)
+		    {
+		      PyErr_SetString (PyExc_RuntimeError,
+				       _("frame_arg list must contain a Python tuple."));
+		      goto args_error;
+		    }
+
+		  /* Each element in the frame arguments list should be a
+		     tuple containing two elements.  The argument name,
+		     which can be a string or a gdb.Symbol, and the
+		     value.  */
+
+		  /* Name.  */
+		  sym = PyTuple_GetItem (sym_tuple, 0);
+		  if (! sym)
+		      goto args_error;
+
+		  /* Value.  */
+		  value = PyTuple_GetItem (sym_tuple, 1);
+		  if (! value)
+		    goto args_error;
+
+		  /* For arg name, the user can return a symbol or a
+		     string.  */
+		  if (PyString_Check (sym))
+		    {
+		      sym_name = PyString_AsString (sym);
+		      language = current_language;
+		      if (! sym_name)
+			goto args_error;
+		    }
+		  else
+		    {
+		      symbol = symbol_object_to_symbol (sym);
+		      sym_name = SYMBOL_PRINT_NAME (symbol);
+		      if (language_mode == language_mode_auto)
+			language = language_def (SYMBOL_LANGUAGE (symbol));
+		      else
+			language = current_language;
+		    }
+
+		  annotate_arg_begin ();
+		  ui_out_field_string (out, "name", sym_name);
+		  ui_out_text (out, "=");
+
+		  val = value_object_to_value (value);
+		  if (! val)
+		    {
+		      PyErr_SetString (PyExc_RuntimeError,
+				       _("Invalid value in frame."));
+		      goto args_error;
+		    }
+
+		  annotate_arg_value (value_type (val));
+
+		  opts.deref_ref = 1;
+
+		  /* True in "summary" mode, false otherwise.  */
+		  opts.summary = !strcmp (print_args_type, "scalars");
+
+		  TRY_CATCH (except, RETURN_MASK_ALL)
+		    {
+		      common_val_print (val, stb->stream, 2, &opts, language);
+		    }
+		  if (except.reason > 0)
+		    {
+		      PyErr_SetString (PyExc_RuntimeError,
+				       except.message);
+		      goto args_error;
+		    }
+
+		  ui_out_field_stream (out, "value", stb);
+
+		  if (size != 1 && list_index < size-1)
+		    ui_out_text (out, ", ");
+		  annotate_arg_end ();
+		}
+	    }
+	}
+      else
+	goto args_error;
+    }
+  ui_out_text (out, ")");
+
+  do_cleanups (old_chain);
+  return 1;
+
+ args_error:
+  do_cleanups (old_chain);
+  return 0;
+}
+
+static int
+py_print_frame (PyObject *filter,
 	     int print_level,
 	     enum print_what print_what,
 	     int print_args,
@@ -263,7 +535,6 @@ print_frame (PyObject *filter,
   char *filename = NULL;
   int line = 0;
   volatile struct gdb_exception except;
-  const struct language_defn *language;
 
   /* First check to see if this frame is to be omitted.  */
   if (PyObject_HasAttrString (filter, "omit"))
@@ -374,136 +645,12 @@ print_frame (PyObject *filter,
   ui_out_field_string (out, "func", func);
 
   /* Frame arguments.  */
-  annotate_frame_args ();
-  ui_out_text (out, " (");
   if (print_args)
     {
-       if (PyObject_HasAttrString (filter, "frame_args"))
-	{
-	  PyObject *result = PyObject_CallMethod (filter, "frame_args", NULL);
-	  struct ui_stream *stb;
-	  struct cleanup *old_chain;
-	  const char *sym_name;
-
-	  stb = ui_out_stream_new (out);
-	  old_chain = make_cleanup_ui_out_stream_delete (stb);
-
-	  if (result)
-	    {
-	      Py_ssize_t size, list_index;
-
-	      if (! PyList_Check (result))
-		{
-		  Py_DECREF (result);
-		  PyErr_SetString (PyExc_RuntimeError,
-				   _("frame_args must return a Python list."));
-		  do_cleanups (old_chain);
-		  goto error;
-		}
-
-	      size = PyList_Size (result);
-
-	      if (size > 0)
-		{
-		  for (list_index = 0; list_index < size; list_index++)
-		    {
-		      PyObject *sym_tuple, *sym, *value;
-		      char *symname;
-		      struct value *val;
-		      struct symbol *symbol;
-
-		      sym_tuple = PyList_GetItem (result, list_index);
-		      if (! sym_tuple)
-			{
-			  Py_DECREF (result);
-			  do_cleanups (old_chain);
-			  goto error;
-			}
-
-		      if (! PyTuple_Check (sym_tuple)
-			  && PyTuple_Size (sym_tuple) != 2)
-			{
-			  Py_DECREF (result);
-
-			  PyErr_SetString (PyExc_RuntimeError,
-					   _("frame_arg list must contain a Python tuple."));
-			  do_cleanups (old_chain);
-			  goto error;
-			}
-
-		      /* Each element in the frame arguments list should be a
-			 tuple containing two elements.  The argument name,
-			 which can be a string or a gdb.Symbol, and the
-			 value.  */
-
-		      /* Name.  */
-		      sym = PyTuple_GetItem (sym_tuple, 0);
-		      if (! sym)
-			{
-			  Py_DECREF (result);
-			  do_cleanups (old_chain);
-			  goto error;
-			}
-
-		      /* Value.  */
-		      value = PyTuple_GetItem (sym_tuple, 1);
-		      if (! value)
-			{
-			  Py_DECREF (result);
-			  do_cleanups (old_chain);
-			  goto error;
-			}
-
-		      /* For arg name, the user can return a symbol or a
-			 string.  */
-		      if (PyString_Check (sym))
-			{
-			  sym_name = PyString_AsString (sym);
-			  language = current_language;
-			  if (! sym_name)
-			    {
-			      Py_DECREF (result);
-			      do_cleanups (old_chain);
-			      goto error;
-			    }
-			}
-		      else
-			{
-			  symbol = symbol_object_to_symbol (sym);
-			  sym_name = SYMBOL_PRINT_NAME (symbol);
-			  if (language_mode == language_mode_auto)
-			    language = language_def (SYMBOL_LANGUAGE (symbol));
-			  else
-			    language = current_language;
-			}
-
-			annotate_arg_begin ();
-			ui_out_field_string (out, "name", sym_name);
-			ui_out_text (out, "=");
-
-			val = value_object_to_value (value);
-
-			annotate_arg_value (value_type (val));
-
-			opts.deref_ref = 1;
-
-			/* True in "summary" mode, false otherwise.  */
-			 opts.summary = !strcmp (print_args_type, "scalars");
-			common_val_print (val, stb->stream, 2, &opts, language);
-			ui_out_field_stream (out, "value", stb);
-			if (size != 1 && list_index < size-1)
-			  ui_out_text (out, ", ");
-			annotate_arg_end ();
-		    }
-		  Py_DECREF (result);
-		}
-	    }
-	  else
-	    goto error;
-	}
+      if (! py_print_args (filter, out, opts, print_args_type))
+	goto error;
     }
 
-  ui_out_text (out, ")");
   if (PyObject_HasAttrString (filter, "filename"))
     {
       PyObject *result = PyObject_CallMethod (filter, "filename", NULL);
@@ -613,7 +760,8 @@ int
 apply_frame_filter (struct frame_info *frame, int print_level,
 		    enum print_what print_what, int print_args,
 		    const char *print_args_type, 
-		    struct ui_out *out)
+		    struct ui_out *out, int print_frame,
+		    int print_locals)
 {
   struct gdbarch *gdbarch = get_frame_arch (frame);
   struct cleanup *cleanups;
@@ -638,16 +786,21 @@ apply_frame_filter (struct frame_info *frame, int print_level,
     goto done;
 
   get_user_print_options (&opts);
-  success =  print_frame (filter, print_level, print_what,
-			  print_args, print_args_type, out, opts,
-			  frame);
-
+  if (print_frame)
+    {
+      success =  py_print_frame (filter, print_level, print_what,
+				 print_args, print_args_type, out, opts,
+				 frame);
+      if (success == 0 && PyErr_Occurred ())
+	gdbpy_print_stack ();
+    }
   
-  /* 'print_frame' can return a frame to "resume" from, in the case
-     that frames have been elided.  If the return value is NULL, also
-     check to see if this was because a Python error occurred.  */
-  if (success == 0 && PyErr_Occurred())
-    gdbpy_print_stack ();
+  if (print_locals)
+    {
+      success = py_print_locals (filter, opts);
+      if (success == 0 && PyErr_Occurred ())
+	gdbpy_print_stack ();
+    }
 
  done:
   do_cleanups (cleanups);
@@ -655,11 +808,12 @@ apply_frame_filter (struct frame_info *frame, int print_level,
 }
 
 #else /* HAVE_PYTHON */
-
-struct frame_info *
+int
 apply_frame_filter (struct frame_info *frame, int print_level,
 		    enum print_what print_what, int print_args,
-		    struct ui_out *out)
+		    const char *print_args_type,
+		    struct ui_out *out, int print_frame,
+		    int print_locals)
 {
   return NULL;
 }
diff --git a/gdb/python/python.h b/gdb/python/python.h
index 80f7168..55ec72b 100644
--- a/gdb/python/python.h
+++ b/gdb/python/python.h
@@ -39,12 +39,15 @@ int apply_val_pretty_printer (struct type *type, const gdb_byte *valaddr,
 			      const struct value_print_options *options,
 			      const struct language_defn *language);
 
+
 int apply_frame_filter (struct frame_info *frame,
 			int print_level,


hooks/post-receive
--
Repository for Project Archer.


^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2012-03-27 16:39 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-03-27 16:39 [SCM] archer-pmuldoon-python-backtrace: Refactor frame argument printing. Roughly implement print local variables pmuldoon

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).