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).