public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM]  archer-pmuldoon-python-backtrace: Add support for entry arguments and initial support for -stack-list-arguments.
@ 2012-08-23 14:53 pmuldoon
  0 siblings, 0 replies; only message in thread
From: pmuldoon @ 2012-08-23 14:53 UTC (permalink / raw)
  To: archer-commits

The branch, archer-pmuldoon-python-backtrace has been updated
       via  8a1e1772259968d49dd6a96c4e9b86fdbce3e130 (commit)
      from  ce126c971ee4f1908c026de832cedd633c4028b5 (commit)

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

- Log -----------------------------------------------------------------
commit 8a1e1772259968d49dd6a96c4e9b86fdbce3e130
Author: Phil Muldoon <pmuldoon@redhat.com>
Date:   Thu Aug 23 15:52:41 2012 +0100

    Add support for entry arguments and initial support for -stack-list-arguments.

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

Summary of changes:
 gdb/python/lib/gdb/BaseFrameWrapper.py         |    4 +-
 gdb/python/py-framefilter.c                    |  460 ++++++++++++++++++------
 gdb/testsuite/gdb.python/py-framefilter-mi.c   |   27 ++-
 gdb/testsuite/gdb.python/py-framefilter-mi.exp |   40 ++-
 4 files changed, 403 insertions(+), 128 deletions(-)

First 500 lines of diff:
diff --git a/gdb/python/lib/gdb/BaseFrameWrapper.py b/gdb/python/lib/gdb/BaseFrameWrapper.py
index e4ca58d..aa49ad1 100644
--- a/gdb/python/lib/gdb/BaseFrameWrapper.py
+++ b/gdb/python/lib/gdb/BaseFrameWrapper.py
@@ -133,7 +133,7 @@ class FrameVars ():
             if sym.is_argument:
                 continue;
             if self.fetch_b (sym):
-                lvars.append(BaseSymValueWrapper(sym, self.get_value(sym,block)))
+                lvars.append(BaseSymValueWrapper(sym, None))
 
         if len(lvars) == 0:
             return None
@@ -148,7 +148,7 @@ class FrameVars ():
             if not sym.is_argument:
                 continue;
             if self.fetch_b (sym):
-                args.append(BaseSymValueWrapper(sym,self.get_value (sym,block)))
+                args.append(BaseSymValueWrapper(sym,None))
 
         if len(args) == 0:
             return None
diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c
index fd6e26e..9183c54 100644
--- a/gdb/python/py-framefilter.c
+++ b/gdb/python/py-framefilter.c
@@ -23,32 +23,33 @@
 #include "language.h"
 #include "exceptions.h"
 #include "arch-utils.h"
-#include "language.h"
 #include "python.h"
 #include "ui-out.h"
 #include "valprint.h"
 #include "annotate.h"
 #include "hashtab.h"
 #include "mi/mi-cmds.h"
+#include "demangle.h"
 
 #ifdef HAVE_PYTHON
 #include "python-internal.h"
 
-/* Helper function to extract a name, value and language definition
-   from a Python object that conforms SymbolValue interface.  OBJ is
-   the Python object to extract the values from.  **NAME is a
+
+/* Helper function to extract a symbol, name and language definition
+   from a Python object that conforms to the SymbolValue interface.
+   OBJ is the Python object to extract the values from.  **NAME is a
    pass-through argument where the name of the symbol will be written.
-   **VALUE is a pass-through argument where the value corresponding
-   the to the Symbol will be written, and LANGUAGE is also a
-   pass-through argument denoting the language attributed to the
-   Symbol.  Returns 0 on error with the appropriate Python exception
-   set, and 1 on success.  */
-
-static int extract_sym_and_value (PyObject *obj,
-				  char **name, struct value **value,
-				  const struct language_defn **language)
-{
+   **SYM is a pass-through argument where the symbol will be written.
+   In the case of the API returning a string, this will be set to
+   NULL.  **LANGUAGE is also a pass-through argument denoting the
+   language attributed to the Symbol. In the case of **SYM being NULL,
+   this will be set to the current language.  Returns 0 on error with
+   the appropriate Python exception set, and 1 on success.  */
 
+static int
+extract_sym (PyObject *obj, char **name, struct symbol **sym,
+	       const struct language_defn **language)
+{
   if (PyObject_HasAttrString (obj, "symbol"))
     {
       PyObject *result = PyObject_CallMethod (obj, "symbol", NULL);
@@ -66,14 +67,15 @@ static int extract_sym_and_value (PyObject *obj,
 	  if (! *name)
 	    return 0;
 	  *language = current_language;
+	  *sym = NULL;
 	}
       else
 	{
-	  struct symbol *symbol = symbol_object_to_symbol (result);
+	  *sym = symbol_object_to_symbol (result);
 
 	  Py_DECREF (result);
 
-	  if (! symbol)
+	  if (! *sym)
 	    {
 	      PyErr_SetString (PyExc_RuntimeError,
 			       _("Unexpected value.  Expecting a " \
@@ -81,10 +83,10 @@ static int extract_sym_and_value (PyObject *obj,
 	      return 0;
 	    }
 
-	  *name = xstrdup (SYMBOL_PRINT_NAME (symbol));
+	  *name = xstrdup (SYMBOL_PRINT_NAME (*sym));
 
 	  if (language_mode == language_mode_auto)
-	    *language = language_def (SYMBOL_LANGUAGE (symbol));
+	    *language = language_def (SYMBOL_LANGUAGE (*sym));
 	  else
 	    *language = current_language;
 	}
@@ -92,37 +94,52 @@ static int extract_sym_and_value (PyObject *obj,
   else
     {
       PyErr_SetString (PyExc_RuntimeError,
-		       _("Mandatory function 'symbol' not " \
+			 _("Mandatory function 'symbol' not " \
 			 "implemented."));
       return 0;
     }
 
+  return 1;
+}
+
+/* Helper function to extract a value from an object that conforms to
+   the SymbolValue interface.  OBJ is the Python object to extract the
+   value from.  **VALUE is a pass-through argument where the value
+   will be written.  If the object does not have the value attribute,
+   or provides the Python None for a value, **VALUE will be set to
+   NULL and this function will return as successful.  Returns 0 on
+   error with the appropriate Python exception set, and 1 on
+   success.  */
+
+static int
+extract_value (PyObject *obj, struct value **value)
+{
   if (PyObject_HasAttrString (obj, "value"))
     {
-      PyObject *result = PyObject_CallMethod (obj, "value", NULL);
+      PyObject *vresult = PyObject_CallMethod (obj, "value", NULL);
 
-      if (! result)
+      if (! vresult)
+	return 0;
+
+      if (vresult == Py_None)
 	{
-	  xfree (*name);
-	  return 0;
+	  Py_DECREF (vresult);
+	  *value = NULL;
+	  return 1;
 	}
+      else
+	{
+	  *value = convert_value_from_python (vresult);
+	  Py_DECREF (vresult);
 
-      *value = convert_value_from_python (result);
+	  if (*value == NULL)
+	    return 0;
 
-      Py_DECREF (result);
-      if (! *value)
-	{
-	  xfree (*name);
-	  return 0;
+	  return 1;
 	}
     }
   else
-    {
-      PyErr_SetString (PyExc_RuntimeError,
-		       _("Mandatory function 'value' not " \
-			 "implemented."));
-      return 0;
-    }
+    *value = NULL;
 
   return 1;
 }
@@ -145,7 +162,7 @@ py_print_type (struct ui_out *out, struct value *val)
       stb = mem_fileopen ();
       cleanup = make_cleanup_ui_file_delete (stb);
       type = check_typedef (value_type (val));
-      type_print (type, "", stb, -1);
+      type_print (value_type (val), "", stb, -1);
       ui_out_field_stream (out, "type", stb);
       do_cleanups (cleanup);
     }
@@ -166,30 +183,54 @@ py_print_type (struct ui_out *out, struct value *val)
 
 static int
 py_print_value (struct ui_out *out, struct value *val,
+		struct value_print_options opts,
+		int mi_print_type,
 		const struct language_defn *language)
 {
-  volatile struct gdb_exception except;
+  int should_print = 0;
 
-  TRY_CATCH (except, RETURN_MASK_ALL)
+  /* MI disallows different value types against different options the
+     client passes, so test type against option.  For CLI print all
+     values.  */
+  if (ui_out_is_mi_like_p (out))
     {
-      struct ui_file *stb;
-      struct cleanup *cleanup;
-      struct value_print_options opts;
+      struct type *type;
 
-      stb = mem_fileopen ();
-      cleanup = make_cleanup_ui_file_delete (stb);
-      get_user_print_options (&opts);
-      opts.deref_ref = 1;
-      common_val_print (val, stb, 2, &opts, language);
-      ui_out_field_stream (out, "value", stb);
-      do_cleanups (cleanup);
+      type = value_type (val);
+      check_typedef (type);
+      if (mi_print_type == PRINT_ALL_VALUES
+	  || (mi_print_type == PRINT_SIMPLE_VALUES
+	      && TYPE_CODE (type) != TYPE_CODE_ARRAY
+	      && TYPE_CODE (type) != TYPE_CODE_STRUCT
+	      && TYPE_CODE (type) != TYPE_CODE_UNION))
+	should_print = 1;
     }
-  if (except.reason > 0)
+  else
+    should_print = 1;
+
+  if (should_print)
     {
-      PyErr_SetString (PyExc_RuntimeError,
-		       except.message);
-      return 0;
+      volatile struct gdb_exception except;
+
+      TRY_CATCH (except, RETURN_MASK_ALL)
+	{
+	  struct ui_file *stb;
+	  struct cleanup *cleanup;
+
+	  stb = mem_fileopen ();
+	  cleanup = make_cleanup_ui_file_delete (stb);
+	  common_val_print (val, stb, 0, &opts, language);
+	  ui_out_field_stream (out, "value", stb);
+	  do_cleanups (cleanup);
+	}
+      if (except.reason > 0)
+	{
+	  PyErr_SetString (PyExc_RuntimeError,
+			   except.message);
+	  return 0;
+	}
     }
+
   return 1;
 }
 
@@ -239,12 +280,113 @@ get_py_iter_from_func (PyObject *filter, char *func)
 }
 
 static int
+py_print_single_arg (struct ui_out *out,
+		     char *sym_name,
+		     struct frame_arg *fa,
+		     struct value *fv,
+		     struct value_print_options opts,
+		     int mi_print_type,
+		     const char *print_args_type,
+		     int print_mi_args_flag,
+		     const struct language_defn *language)
+{
+  struct value *val;
+  struct cleanup *inner_cleanup =
+    make_cleanup (null_cleanup, NULL);
+
+  if (fa)
+    {
+      language = language_def (SYMBOL_LANGUAGE (fa->sym));
+      val = fa->val;
+    }
+  else
+    val = fv;
+
+  if (print_mi_args_flag || mi_print_type != PRINT_NO_VALUES)
+    {
+      inner_cleanup =
+	make_cleanup_ui_out_tuple_begin_end (out,
+					     NULL);
+    }
+
+  annotate_arg_begin ();
+
+  if (fa)
+    {
+      struct ui_file *stb;
+
+      stb = mem_fileopen ();
+
+      fprintf_symbol_filtered (stb, SYMBOL_PRINT_NAME (fa->sym),
+			       SYMBOL_LANGUAGE (fa->sym),
+			       DMGL_PARAMS | DMGL_ANSI);
+      if (fa->entry_kind == print_entry_values_compact)
+	{
+	  fputs_filtered ("=", stb);
+
+	  fprintf_symbol_filtered (stb, SYMBOL_PRINT_NAME (fa->sym),
+				   SYMBOL_LANGUAGE (fa->sym),
+				   DMGL_PARAMS | DMGL_ANSI);
+	}
+      if (fa->entry_kind == print_entry_values_only
+	  || fa->entry_kind == print_entry_values_compact)
+	{
+	  fputs_filtered ("@entry", stb);
+	}
+      ui_out_field_stream (out, "name", stb);
+      ui_file_delete (stb);
+    }
+  else
+    ui_out_field_string (out, "name", sym_name);
+
+  annotate_arg_name_end ();
+
+  if (! ui_out_is_mi_like_p (out))
+    ui_out_text (out, "=");
+
+  if (print_mi_args_flag)
+    ui_out_field_int (out, "arg", 1);
+
+  opts.deref_ref = 1;
+  if (ui_out_is_mi_like_p (out)
+      && mi_print_type == PRINT_SIMPLE_VALUES)
+    {
+      if (! py_print_type (out, val))
+	goto error;
+    }
+
+  if (! ui_out_is_mi_like_p (out))
+    {
+      opts.summary = !strcmp (print_args_type, "scalars");
+    }
+
+  annotate_arg_value (value_type (val));
+  if (! ui_out_is_mi_like_p (out)
+      || (ui_out_is_mi_like_p (out)
+	  && mi_print_type != PRINT_NO_VALUES))
+    {
+
+      if (! py_print_value (out, val, opts, mi_print_type, language))
+	goto error;
+    }
+
+  do_cleanups (inner_cleanup);
+
+  return 1;
+
+ error:
+  do_cleanups (inner_cleanup);
+  return 0;
+}
+
+static int
 enumerate_args (PyObject *iter,
 		struct ui_out *out,
 		struct value_print_options opts,
 		int mi_print_type,
 		const char *print_args_type,
-		int print_mi_args_flag)
+		int print_mi_args_flag,
+		struct frame_info *frame)
 {
   PyObject *item;
 
@@ -258,63 +400,103 @@ enumerate_args (PyObject *iter,
     {
       const struct language_defn *language;
       char *sym_name;
+      struct symbol *sym;
       struct value *val;
-      int value_success = 0;
+      int success = 0;
       volatile struct gdb_exception except;
-      struct cleanup *inner_cleanup =
-	make_cleanup (null_cleanup, NULL);
+      struct frame_arg arg, entryarg;
+
+      success = extract_sym (item, &sym_name, &sym, &language);
+      if (! success)
+	{
+	  Py_DECREF (item);
+	  goto error;
+	}
+
+      success = extract_value (item, &val);
+      if (! success)
+	{
+	  xfree (sym_name);
+	  Py_DECREF (item);
+	  goto error;
+	}
 
-      value_success = extract_sym_and_value (item,
-					     &sym_name,
-					     &val,
-					     &language);
       Py_DECREF (item);
       item = NULL;
 
-      if (! value_success)
-	goto error;
-
-      if (ui_out_is_mi_like_p (out))
+      /* If the object did not provide a value, read it.  */
+      if (! val)
 	{
-	  if(mi_print_type != PRINT_NO_VALUES)
+
+	  /* If there is no value, and also no symbol, set error and
+	     exit.  */
+	  if (! sym)
 	    {
-	      inner_cleanup =
-		make_cleanup_ui_out_tuple_begin_end (out,
-						     NULL);
+	      PyErr_SetString (PyExc_RuntimeError,
+			       _("No symbol or value provided."));
+	      xfree (sym_name);
+	      goto error;
 	    }
-	}
 
-      annotate_arg_begin ();
-      ui_out_field_string (out, "name", sym_name);
+	    read_frame_arg (sym, frame, &arg, &entryarg);
+	}
 
-      if (! ui_out_is_mi_like_p (out))
-	ui_out_text (out, "=");
 
-      if (print_mi_args_flag)
-	ui_out_field_int (out, "arg", 1);
+      /* If the object has provided a value, we print that.  */
+      if (val)
+	py_print_single_arg (out,
+			     sym_name,
+			     NULL,
+			     val,
+			     opts,
+			     mi_print_type,
+			     print_args_type,
+			     print_mi_args_flag,
+			     language);
+      else
+	{
+	  /* The object has not provided a value, so this is a frame
+	     argument read by GDB.  In this case we have to account
+	     for entry-values.  */
+
+	  if (arg.entry_kind != print_entry_values_only)
+	    py_print_single_arg (out,
+				 NULL,
+				 &arg,
+				 NULL,
+				 opts,
+				 mi_print_type,
+				 print_args_type,
+				 print_mi_args_flag,
+				 NULL);
+
+
+	  if (entryarg.entry_kind != print_entry_values_no)
+	    {
+	      if (arg.entry_kind != print_entry_values_only)
+		{
+		  ui_out_text (out, ", ");
+		  ui_out_wrap_hint (out, "    ");
+		}
 
-      annotate_arg_value (value_type (val));
-      opts.deref_ref = 1;
+	      py_print_single_arg (out,
+				   NULL,
+				   &entryarg,
+				   NULL,
+				   opts,
+				   mi_print_type,
+				   print_args_type,
+				   print_mi_args_flag,
+				   NULL);
 
-      if (ui_out_is_mi_like_p (out)
-	  && mi_print_type == PRINT_SIMPLE_VALUES)
-	{
-	  py_print_type (out, val);
-	}
+	    }
 
-      if (! ui_out_is_mi_like_p (out))
-	{
-	  opts.summary = !strcmp (print_args_type, "scalars");
+	  xfree (arg.error);
+	  xfree (entryarg.error);
 	}


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


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

only message in thread, other threads:[~2012-08-23 14:53 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-08-23 14:53 [SCM] archer-pmuldoon-python-backtrace: Add support for entry arguments and initial support for -stack-list-arguments 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).