public inbox for archer-commits@sourceware.org
help / color / mirror / Atom feed
* [SCM]  archer-pmuldoon-python-backtrace: Add MI support
@ 2012-07-20 13:33 pmuldoon
  0 siblings, 0 replies; only message in thread
From: pmuldoon @ 2012-07-20 13:33 UTC (permalink / raw)
  To: archer-commits

The branch, archer-pmuldoon-python-backtrace has been updated
       via  33561fe62ab2936dceda596fd2115807a8b16f15 (commit)
      from  69d2d6b96038fb7177007f1999f6a7e8905bd6e1 (commit)

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

- Log -----------------------------------------------------------------
commit 33561fe62ab2936dceda596fd2115807a8b16f15
Author: Phil Muldoon <pmuldoon@redhat.com>
Date:   Fri Jul 20 14:32:46 2012 +0100

    Add MI support

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

Summary of changes:
 gdb/mi/mi-cmd-stack.c                          |   74 ++++++++++++++----
 gdb/mi/mi-cmd-var.c                            |    9 ++
 gdb/mi/mi-cmds.c                               |    1 +
 gdb/mi/mi-cmds.h                               |    4 +
 gdb/python/py-framefilter.c                    |   41 +++++++---
 gdb/testsuite/gdb.python/py-framefilter-mi.c   |  102 ++++++++++++++++++++++++
 gdb/testsuite/gdb.python/py-framefilter-mi.exp |   68 ++++++++++++++++
 gdb/testsuite/gdb.python/py-framefilter.exp    |    6 ++
 8 files changed, 278 insertions(+), 27 deletions(-)
 create mode 100644 gdb/testsuite/gdb.python/py-framefilter-mi.c
 create mode 100644 gdb/testsuite/gdb.python/py-framefilter-mi.exp

First 500 lines of diff:
diff --git a/gdb/mi/mi-cmd-stack.c b/gdb/mi/mi-cmd-stack.c
index fe3e0bf..82451bc 100644
--- a/gdb/mi/mi-cmd-stack.c
+++ b/gdb/mi/mi-cmd-stack.c
@@ -32,13 +32,24 @@
 #include "language.h"
 #include "valprint.h"
 #include "exceptions.h"
-
+#include "utils.h"
+#include "python/python.h"
+#include <ctype.h>
 enum what_to_list { locals, arguments, all };
 
 static void list_args_or_locals (enum what_to_list what, 
 				 enum print_values values,
 				 struct frame_info *fi);
 
+/* True if we want to allow Python-based frame filters.  */
+static int frame_filters = 0;
+
+void
+stack_enable_frame_filters (void)
+{
+  frame_filters = 1;
+}
+
 /* Print a list of the stack frames.  Args can be none, in which case
    we want to print the whole backtrace, or a pair of numbers
    specifying the frame numbers at which to start and stop the
@@ -53,14 +64,28 @@ mi_cmd_stack_list_frames (char *command, char **argv, int argc)
   int i;
   struct cleanup *cleanup_stack;
   struct frame_info *fi;
+  int result = 0;
+  int raw_arg = 0;
+  int j;
 
-  if (argc > 2 || argc == 1)
-    error (_("-stack-list-frames: Usage: [FRAME_LOW FRAME_HIGH]"));
+  if (argc)
+    {
+      /* Find 'raw-frames' at argv[0] if passed as an argument */
+      for (j = 0; j < strlen (argv[0]); j++)
+	argv[0][j] = tolower (argv[0][j]);
+
+      if (subset_compare (argv[0], "raw-frames"))
+	raw_arg = 1;
+    }
 
-  if (argc == 2)
+  if ((argc > 3 && ! raw_arg) || (argc == 1 && ! raw_arg)
+      || (argc == 2 && raw_arg))
+    error (_("-stack-list-frames: Usage: [RAW-FRAMES FRAME_LOW FRAME_HIGH]"));
+
+  if (argc == 3 || argc == 2)
     {
-      frame_low = atoi (argv[0]);
-      frame_high = atoi (argv[1]);
+      frame_low = atoi (argv[0 + raw_arg]);
+      frame_high = atoi (argv[1 + raw_arg]);
     }
   else
     {
@@ -82,16 +107,35 @@ mi_cmd_stack_list_frames (char *command, char **argv, int argc)
 
   cleanup_stack = make_cleanup_ui_out_list_begin_end (current_uiout, "stack");
 
-  /* Now let's print the frames up to frame_high, or until there are
-     frames in the stack.  */
-  for (;
-       fi && (i <= frame_high || frame_high == -1);
-       i++, fi = get_prev_frame (fi))
+  if (! raw_arg && frame_filters)
     {
-      QUIT;
-      /* Print the location and the address always, even for level 0.
-         If args is 0, don't print the arguments.  */
-      print_frame_info (fi, 1, LOC_AND_ADDRESS, 0 /* args */ );
+      int count = frame_high;
+
+      if (frame_high != -1)
+	count = (frame_high - frame_low) + 1;
+      result = apply_frame_filter (fi, 1, LOC_AND_ADDRESS, 0,
+				   0 /* print args */, current_uiout,
+				   0 /* show locals */, count);
+    }
+
+  /* Run the inbuilt backtrace if there are no filters registered, or
+     if there was an error in the Python backtracing output, or if
+     frame-filters are disabled.  */
+  if (! frame_filters || raw_arg || result == PY_BT_ERROR
+      || result == PY_BT_NO_FILTERS)
+
+    {
+      /* Now let's print the frames up to frame_high, or until there are
+	 frames in the stack.  */
+      for (;
+	   fi && (i <= frame_high || frame_high == -1);
+	   i++, fi = get_prev_frame (fi))
+	{
+	  QUIT;
+	  /* Print the location and the address always, even for level 0.
+	     If args is 0, don't print the arguments.  */
+	  print_frame_info (fi, 1, LOC_AND_ADDRESS, 0 /* args */ );
+	}
     }
 
   do_cleanups (cleanup_stack);
diff --git a/gdb/mi/mi-cmd-var.c b/gdb/mi/mi-cmd-var.c
index 0603679..ce125db 100644
--- a/gdb/mi/mi-cmd-var.c
+++ b/gdb/mi/mi-cmd-var.c
@@ -835,6 +835,15 @@ mi_cmd_enable_pretty_printing (char *command, char **argv, int argc)
 }
 
 void
+mi_cmd_enable_frame_filters (char *command, char **argv, int argc)
+{
+  if (argc != 0)
+    error (_("-enable-frame-filters: no arguments allowed"));
+
+  stack_enable_frame_filters ();
+}
+
+void
 mi_cmd_var_set_update_range (char *command, char **argv, int argc)
 {
   struct varobj *var;
diff --git a/gdb/mi/mi-cmds.c b/gdb/mi/mi-cmds.c
index 79fbba1..ba56994 100644
--- a/gdb/mi/mi-cmds.c
+++ b/gdb/mi/mi-cmds.c
@@ -60,6 +60,7 @@ struct mi_cmd mi_cmds[] =
     mi_cmd_data_write_register_values},
   { "enable-timings", { NULL, 0 }, mi_cmd_enable_timings},
   { "enable-pretty-printing", { NULL, 0 }, mi_cmd_enable_pretty_printing},
+  { "enable-frame-filters", { NULL, 0 }, mi_cmd_enable_frame_filters},
   { "environment-cd", { NULL, 0 }, mi_cmd_env_cd},
   { "environment-directory", { NULL, 0 }, mi_cmd_env_dir},
   { "environment-path", { NULL, 0 }, mi_cmd_env_path},
diff --git a/gdb/mi/mi-cmds.h b/gdb/mi/mi-cmds.h
index 4d0fc9d..ed2959b 100644
--- a/gdb/mi/mi-cmds.h
+++ b/gdb/mi/mi-cmds.h
@@ -117,6 +117,7 @@ extern mi_cmd_argv_ftype mi_cmd_var_show_attributes;
 extern mi_cmd_argv_ftype mi_cmd_var_show_format;
 extern mi_cmd_argv_ftype mi_cmd_var_update;
 extern mi_cmd_argv_ftype mi_cmd_enable_pretty_printing;
+extern mi_cmd_argv_ftype mi_cmd_enable_frame_filters;
 extern mi_cmd_argv_ftype mi_cmd_var_set_update_range;
 
 /* Description of a single command.  */
@@ -140,6 +141,9 @@ struct mi_cmd
   mi_cmd_argv_ftype *argv_func;
 };
 
+extern void
+stack_enable_frame_filters (void);
+
 /* Lookup a command in the MI command table.  */
 
 extern struct mi_cmd *mi_lookup (const char *command);
diff --git a/gdb/python/py-framefilter.c b/gdb/python/py-framefilter.c
index d10fb63..bb4d4a0 100644
--- a/gdb/python/py-framefilter.c
+++ b/gdb/python/py-framefilter.c
@@ -548,13 +548,15 @@ py_print_frame (PyObject *filter,
       else
 	goto error;
     }
-  
-  annotate_frame_source_end ();
-  
-  ui_out_text (out, "\n");
-  
-  if (has_addr)
-    annotate_frame_end ();
+
+  /* For MI we need to deal with the children population of elided
+     frames, so if MI output detected do not send newline.  */
+  if (! ui_out_is_mi_like_p (out))
+    {
+      if (has_addr)
+	annotate_frame_end ();
+      ui_out_text (out, "\n");
+    }
   
   if (print_locals)
     {
@@ -583,11 +585,21 @@ py_print_frame (PyObject *filter,
 	    {
 	      PyObject *iterator = PyObject_GetIter (result);
 	      PyObject *item;
-	      
+	      struct cleanup *cleanup_stack;
+
 	      if (iterator == NULL)
 		goto error;
-	      
-	      indent = indent + 4;
+
+	      if (ui_out_is_mi_like_p (out))
+		{
+		  cleanup_stack = make_cleanup_ui_out_list_begin_end (out, "children");
+		}
+	      else
+		{
+		  cleanup_stack = make_cleanup (null_cleanup, NULL);
+		  indent = indent + 4;
+		}
+
 	      while ((item = PyIter_Next (iterator)))
 		{
 		  int success =  py_print_frame (item, print_level, print_what,
@@ -595,8 +607,13 @@ py_print_frame (PyObject *filter,
 						 print_locals, out,
 						 opts, indent, levels_printed);
 		  if (success == 0 && PyErr_Occurred ())
-		    goto error;
+		    {
+		      do_cleanups (cleanup_stack);
+		      goto error;
+		    }
 		}
+
+	      do_cleanups (cleanup_stack);
 	    }
 	}     
     }
@@ -676,7 +693,7 @@ apply_frame_filter (struct frame_info *frame, int print_level,
 				    eq_printed_frame_entry,
 				    NULL);
 
-      while ((item = PyIter_Next (iterator)))
+      while ((item = PyIter_Next (iterator)) && count--)
 	{
 	  success =  py_print_frame (item, print_level, print_what,
 				     print_args, print_args_type,
diff --git a/gdb/testsuite/gdb.python/py-framefilter-mi.c b/gdb/testsuite/gdb.python/py-framefilter-mi.c
new file mode 100644
index 0000000..25a8a6e
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-framefilter-mi.c
@@ -0,0 +1,102 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   Copyright 2008-2012 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+
+void funca(void);
+int count = 0;
+
+void end_func (void)
+{
+  const char *str = "The End";
+  const char *st2 = "Is Near";
+  int b = 12;
+  short c = 5;
+
+  return; /* Backtrace end breakpoint */
+}
+
+void funcb(int j)
+{
+  struct foo
+  {
+    int a;
+    int b;
+  };
+
+  struct foo bar;
+
+  bar.a = 42;
+  bar.b = 84;
+
+  funca();
+  return;
+}
+
+void funca(void)
+{
+  if (count < 10)
+    {
+      count++;
+      funcb(count);
+    }
+
+  end_func();
+  return;
+}
+
+
+void func1(void)
+{
+  funca();
+  return;
+}
+
+int func2(void)
+{  
+  
+  func1();
+  return 1;
+}
+
+void func3(int i)
+{
+  func2();
+
+  return;
+}
+
+int func4(int j)
+{
+  func3(j);
+
+  return 2;
+}
+
+int func5(int f, int d)
+{
+  int i = 0;
+  char *random = "random";
+  i=i+f;
+  
+  func4(i);
+  return i;
+}
+    
+main()
+{
+  func5(3,5);
+}
diff --git a/gdb/testsuite/gdb.python/py-framefilter-mi.exp b/gdb/testsuite/gdb.python/py-framefilter-mi.exp
new file mode 100644
index 0000000..f6e3444
--- /dev/null
+++ b/gdb/testsuite/gdb.python/py-framefilter-mi.exp
@@ -0,0 +1,68 @@
+# Copyright (C) 2012 Free Software Foundation, Inc.
+
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.
+
+# This file is part of the GDB testsuite.  It tests Python-based
+# frame-filters.
+load_lib mi-support.exp
+load_lib gdb-python.exp
+
+set MIFLAGS "-i=mi2"
+global hex
+
+gdb_exit
+if [mi_gdb_start] {
+    continue
+}
+
+standard_testfile py-framefilter-mi.c
+set pyfile py-framefilter.py
+
+if  { [gdb_compile "${srcdir}/${subdir}/${srcfile}" "${binfile}" executable {debug additional_flags=-DMI}] != "" } {
+    untested ${testfile}.exp
+    return -1
+}
+
+mi_delete_breakpoints
+mi_gdb_reinitialize_dir $srcdir/$subdir
+mi_gdb_load ${binfile}
+
+if {[lsearch -exact [mi_get_features] python] < 0} {
+    unsupported "python support is disabled"
+    return -1
+}
+
+mi_runto main
+
+set remote_python_file [remote_download host ${srcdir}/${subdir}/${pyfile}]
+
+mi_gdb_test "python execfile ('${remote_python_file}')" ""
+
+mi_continue_to_line [gdb_get_line_number {Backtrace end breakpoint} ${srcfile}] \
+  "step to breakpoint"
+
+mi_gdb_test "-enable-frame-filters" ""
+mi_gdb_test "-stack-list-frames" \
+    "\\^done,stack=\\\[level=\"0\",addr=\"$hex\",func=\"cnuf_dne\".*,level=\"1\",addr=\"$hex\",func=\"acnuf\".*,level=\"2\",addr=\"$hex\",func=\"bcnuf\".*,level=\"3\",addr=\"$hex\",func=\"acnuf\".*,level=\"22\",addr=\"$hex\",func=\"1cnuf\".*,children=\\\[level=\"23\",addr=\"$hex\",func=\"func2\".*\\\],level=\"24\",addr=\"$hex\",func=\"3cnuf\".*,level=\"27\",addr=\"$hex\",func=\"niam\".*\\\]" \
+    "filtered stack listing"
+mi_gdb_test "-stack-list-frames 0 3" \
+    "\\^done,stack=\\\[level=\"0\",addr=\"$hex\",func=\"cnuf_dne\".*,level=\"1\",addr=\"$hex\",func=\"acnuf\".*,level=\"2\",addr=\"$hex\",func=\"bcnuf\".*,level=\"3\",addr=\"$hex\",func=\"acnuf\".*\\\]" \
+    "filtered stack list 0 3"
+mi_gdb_test "-stack-list-frames 22 24" \
+    "\\^done,stack=\\\[level=\"22\",addr=\"$hex\",func=\"1cnuf\".*,children=\\\[level=\"23\",addr=\"$hex\",func=\"func2\".*\\\],level=\"24\",addr=\"$hex\",func=\"3cnuf\".*\\\]" \
+    "filtered stack list 0 3"
+
+
+remote_file host delete ${remote_python_file}
+
diff --git a/gdb/testsuite/gdb.python/py-framefilter.exp b/gdb/testsuite/gdb.python/py-framefilter.exp
index 0b998a1..c845ebe 100644
--- a/gdb/testsuite/gdb.python/py-framefilter.exp
+++ b/gdb/testsuite/gdb.python/py-framefilter.exp
@@ -75,5 +75,11 @@ gdb_test_no_output "set python frame-filter disable global Reverse"
 gdb_test "bt" \
     {.*#0.*end_func.*#22.*in func1.*#27.*in main ().*}
 
+gdb_test "bt -2" \
+    {.*#26.*func5.*#27.*in main ().*}
+
+gdb_test "bt 3" \
+    {.*#0.*end_func.*#1.*in funca ().*#2.*in funcb ().*}
+
 remote_file host delete ${remote_python_file}
 


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


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

only message in thread, other threads:[~2012-07-20 13:33 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-20 13:33 [SCM] archer-pmuldoon-python-backtrace: Add MI support 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).