2013-05-10 Phil Muldoon <pmuldoon@redhat.com>

* stack.c (backtrace_command_1): Add "no-filters", and Python frame
	filter logic.
	(backtrace_command): Add "no-filters" option parsing.
	(_initialize_stack): Alter help to reflect "no-filters" option.
	* Makefile.in (SUBDIR_PYTHON_OBS): Add py-framefilter.o
	(SUBDIR_PYTHON_SRCS): Add py-framefilter.c
	(py-frame.o): Add target
	* data-directory/Makefile.in (PYTHON_DIR): Add Python frame
	filter files.
	* python/python.h: Add new frame filter constants, and flag enum.
	(apply_frame_filter): Add definition.
	* python/python.c (apply_frame_filter): New non-Python
	enabled function.
	* python/py-utils.c (py_xdecref): New function.
	(make_cleanup_py_xdecref): Ditto.
	* python/py-objfile.c: Declare frame_filters dictionary.
	(objfpy_dealloc): Add frame_filters dealloc.
	(objfpy_new): Initialize frame_filters attribute.
	(objfile_to_objfile_object): Ditto.
	(objfpy_get_frame_filters): New function.
	(objfpy_set_frame_filters): New function.
	* python/py-progspace.c: Declare frame_filters dictionary.
	(pspy_dealloc): Add frame_filters dealloc.
	(pspy_new): Initialize frame_filters attribute.
	(pspacee_to_pspace_object): Ditto.
	(pspy_get_frame_filters): New function.
	(pspy_set_frame_filters): New function.
	* python/py-framefilter.c: New file.
	* python/lib/gdb/command/frame_filters.py: New file.
	* python/lib/gdb/frames.py: New file.
	* python/lib/gdb/__init__.py: Initialize global frame_filters
	dictionary
	* python/lib/gdb/FrameDecorator.py: New file.
	* python/lib/gdb/FrameIterator.py: New file.
	* mi/mi-cmds.c (mi_cmds): Add frame filters command.
	* mi/mi-cmds.h: Declare.
	* mi/mi-cmd-stack.c (mi_cmd_stack_list_frames): Add
	--no-frame-filter logic, and Python frame filter logic.
	(stack_enable_frame_filters): New function.
	(parse_no_frame_option): Ditto.
	(mi_cmd_stack_list_frames): Add --no-frame-filter and Python frame
	filter logic.
	(mi_cmd_stack_list_locals): Ditto.
	(mi_cmd_stack_list_args): Ditto.
	(mi_cmd_stack_list_variables): Ditto.
	* NEWS: Add frame filter note.

2013-05-10  Phil Muldoon  <pmuldoon@redhat.com>

	* gdb.python/py-framefilter.py: New File.
	* gdb.python/py-framefilter-mi.exp: Ditto.
	* gdb.python/py-framefilter.c: Ditto.
	* gdb.python/py-framefilter-mi.exp: Ditto.
	* gdb.python/py-framefilter-mi.c: Ditto,
	* gdb.python/py-framefilter-gdb.py.in: Ditto.

2013-05-10 Phil Muldoon  <pmuldoon@redhat.com>

	* gdb.texinfo (Backtrace): Add "no-filter" argument.
	(Python API): Add Frame	Filters API, Frame Wrapper API,
	Writing a Frame Filter/Wrapper,	Managing Management of Frame
	Filters chapter entries.
	(Frame Filters API): New Node.
	(Frame Wrapper API): New Node.
	(Writing a Frame Filter): New Node.
	(Managing Frame Filters): New Node.
	(Progspaces In Python): Add note about frame_filters attribute.
	(Objfiles in Python): Ditto.
	(GDB/MI Stack Manipulation): Add -enable-frame-filters command,
	@anchors and --no-frame-filters option to -stack-list-variables,
	-stack-list-frames, -stack-list-locals and -stack-list-arguments
	commands.
This commit is contained in:
Phil Muldoon
2013-05-10 10:26:03 +00:00
parent 3ecb733811
commit 1e611234ee
29 changed files with 4846 additions and 88 deletions

View File

@ -1,3 +1,12 @@
2013-05-10 Phil Muldoon <pmuldoon@redhat.com>
* gdb.python/py-framefilter.py: New File.
* gdb.python/py-framefilter-mi.exp: Ditto.
* gdb.python/py-framefilter.c: Ditto.
* gdb.python/py-framefilter-mi.exp: Ditto.
* gdb.python/py-framefilter-mi.c: Ditto,
* gdb.python/py-framefilter-gdb.py.in: Ditto.
2013-05-08 Tom Tromey <tromey@redhat.com>
* gdb.base/solib-search.exp: Set test name for "set

View File

@ -0,0 +1,48 @@
# Copyright (C) 2013 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.
import gdb
import itertools
from gdb.FrameDecorator import FrameDecorator
class FrameObjFile ():
def __init__ (self):
self.name = "Filter1"
self.priority = 1
self.enabled = False
gdb.current_progspace().frame_filters ["Progspace" + self.name] = self
gdb.current_objfile().frame_filters ["ObjectFile" + self.name] = self
def filter (self, frame_iter):
return frame_iter
class FrameObjFile2 ():
def __init__ (self):
self.name = "Filter2"
self.priority = 100
self.enabled = True
gdb.current_progspace().frame_filters ["Progspace" + self.name] = self
gdb.current_objfile().frame_filters ["ObjectFile" + self.name] = self
def filter (self, frame_iter):
return frame_iter
FrameObjFile()
FrameObjFile2()

View File

@ -0,0 +1,138 @@
/* This testcase is part of GDB, the GNU debugger.
Copyright 2013 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/>. */
#include <stdlib.h>
void funca(void);
int count = 0;
typedef struct
{
char *nothing;
int f;
short s;
} foobar;
void end_func (int foo, char *bar, foobar *fb, foobar bf)
{
const char *str = "The End";
const char *st2 = "Is Near";
int b = 12;
short c = 5;
{
int d = 15;
int e = 14;
const char *foo = "Inside block";
{
int f = 42;
int g = 19;
const char *bar = "Inside block x2";
{
short h = 9;
h = h +1; /* Inner test breakpoint */
}
}
}
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)
{
foobar fb;
foobar *bf;
if (count < 10)
{
count++;
funcb(count);
}
fb.nothing = "Foo Bar";
fb.f = 42;
fb.s = 19;
bf = malloc (sizeof (foobar));
bf->nothing = malloc (128);
bf->nothing = "Bar Foo";
bf->f = 24;
bf->s = 91;
end_func(21, "Param", bf, fb);
free (bf->nothing);
free (bf);
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);
}

View File

@ -0,0 +1,179 @@
# Copyright (C) 2013 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"
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}')" ".*\\^done." \
"Load python file"
# Multiple blocks test
mi_continue_to_line [gdb_get_line_number {Inner test breakpoint} ${srcfile}] \
"step to breakpoint"
mi_gdb_test "-stack-list-locals --all-values" \
"\\^done,locals=\\\[{name=\"h\",value=\"9\"},{name=\"f\",value=\"42\"},{name=\"g\",value=\"19\"},{name=\"bar\",value=\"$hex \\\\\"Inside block x2\\\\\"\"},{name=\"d\",value=\"15\"},{name=\"e\",value=\"14\"},{name=\"foo\",value=\"$hex \\\\\"Inside block\\\\\"\"},{name=\"str\",value=\"$hex \\\\\"The End\\\\\"\"},{name=\"st2\",value=\"$hex \\\\\"Is Near\\\\\"\"},{name=\"b\",value=\"12\"},{name=\"c\",value=\"5\"}\\\]" \
"stack-list-locals --all-values"
mi_gdb_test "-enable-frame-filters" ".*\\^done." "enable frame filters"
mi_gdb_test "-stack-list-locals --all-values" \
"\\^done,locals=\\\[{name=\"h\",value=\"9\"},{name=\"f\",value=\"42\"},{name=\"g\",value=\"19\"},{name=\"bar\",value=\"$hex \\\\\"Inside block x2\\\\\"\"},{name=\"d\",value=\"15\"},{name=\"e\",value=\"14\"},{name=\"foo\",value=\"$hex \\\\\"Inside block\\\\\"\"},{name=\"str\",value=\"$hex \\\\\"The End\\\\\"\"},{name=\"st2\",value=\"$hex \\\\\"Is Near\\\\\"\"},{name=\"b\",value=\"12\"},{name=\"c\",value=\"5\"}\\\]" \
"stack-list-locals --all-values frame filters enabled"
mi_continue_to_line [gdb_get_line_number {Backtrace end breakpoint} ${srcfile}] \
"step to breakpoint"
mi_gdb_test "-stack-list-frames" \
"\\^done,stack=\\\[frame={level=\"0\",addr=\"$hex\",func=\"cnuf_dne\".*},frame={level=\"1\",addr=\"$hex\",func=\"acnuf\".*},frame={level=\"2\",addr=\"$hex\",func=\"bcnuf\".*},frame={level=\"3\",addr=\"$hex\",func=\"acnuf\".*},frame={level=\"22\",addr=\"$hex\",func=\"1cnuf\".*,children=\\\[frame={level=\"23\",addr=\"$hex\",func=\"func2\".*}\\\]},frame={level=\"24\",addr=\"$hex\",func=\"3cnuf\".*},frame={level=\"27\",addr=\"$hex\",func=\"niam\".*}\\\].*" \
"filtered stack listing"
mi_gdb_test "-stack-list-frames 0 3" \
"\\^done,stack=\\\[frame={level=\"0\",addr=\"$hex\",func=\"cnuf_dne\".*},frame={level=\"1\",addr=\"$hex\",func=\"acnuf\".*},frame={level=\"2\",addr=\"$hex\",func=\"bcnuf\".*},frame={level=\"3\",addr=\"$hex\",func=\"acnuf\".*}\\\]" \
"filtered stack list 0 3"
mi_gdb_test "-stack-list-frames 22 24" \
"\\^done,stack=\\\[frame={level=\"22\",addr=\"$hex\",func=\"1cnuf\".*,children=\\\[frame={level=\"23\",addr=\"$hex\",func=\"func2\".*}\\\]},frame={level=\"24\",addr=\"$hex\",func=\"3cnuf\".*}\\\]" \
"filtered stack list 22 24"
#stack list arguments
mi_gdb_test "-stack-list-arguments 0" \
"\\^done,stack-args=\\\[frame={level=\"0\",args=\\\[name=\"foo\",name=\"bar\",name=\"fb\",name=\"bf\"\\\]},frame={level=\"1\",args=\\\[\\\]},frame={level=\"2\",args=\\\[name=\"j\"\\\]},.*frame={level=\"22\",args=\\\[\\\],children=\\\[frame={level=\"23\",args=\\\[\\\]}\\\]},.*frame={level=\"26\",args=\\\[name=\"f\",name=\"d\"\\\]},frame={level=\"27\",args=\\\[\\\]}\\\]" \
"stack-list-arguments 0"
mi_gdb_test "-stack-list-arguments --no-frame-filters 0" \
"\\^done,stack-args=\\\[frame={level=\"0\",args=\\\[name=\"foo\",name=\"bar\",name=\"fb\",name=\"bf\"\\\]},frame={level=\"1\",args=\\\[\\\]},frame={level=\"2\",args=\\\[name=\"j\"\\\]},.*frame={level=\"22\",args=\\\[\\\]},frame={level=\"23\",args=\\\[\\\]},.*frame={level=\"26\",args=\\\[name=\"f\",name=\"d\"\\\]},frame={level=\"27\",args=\\\[\\\]}\\\]" \
"stack-list-arguments --no-frame-filters 0"
mi_gdb_test "-stack-list-arguments 0 0 3" \
"\\^done,stack-args=\\\[frame={level=\"0\",args=\\\[name=\"foo\",name=\"bar\",name=\"fb\",name=\"bf\"\\\]},frame={level=\"1\",args=\\\[\\\]},frame={level=\"2\",args=\\\[name=\"j\"\\\]},frame={level=\"3\",args=\\\[\\\]}\\\]" \
"stack-list-arguments 0 0 3"
mi_gdb_test "-stack-list-arguments 0 22 27" \
"\\^done,stack-args=\\\[frame={level=\"22\",args=\\\[\\\],children=\\\[frame={level=\"23\",args=\\\[\\\]}\\\]},.*frame={level=\"26\",args=\\\[name=\"f\",name=\"d\"\\\]},frame={level=\"27\",args=\\\[\\\]}\\\]" \
"stack-list-arguments 0 22 27"
mi_gdb_test "-stack-list-arguments 1" \
"\\^done,stack-args=\\\[frame={level=\"0\",args=\\\[{name=\"foo\",value=\"21\"},{name=\"bar\",value=\"$hex \\\\\"Param\\\\\"\"},{name=\"fb\",value=\"$hex\"},{name=\"bf\",value=\"{nothing = $hex \\\\\"Foo Bar\\\\\", f = 42, s = 19}\"}\\\]},frame={level=\"1\",args=\\\[\\\]},frame={level=\"2\",args=\\\[{name=\"j\",value=\"10\"}\\\]},.*frame={level=\"22\",args=\\\[\\\],children=\\\[frame={level=\"23\",args=\\\[\\\]}\\\]},.*frame={level=\"26\",args=\\\[{name=\"f\",value=\"3\"},{name=\"d\",value=\"5\"}\\\]},frame={level=\"27\",args=\\\[\\\]}\\\]" \
"stack-list-arguments 1"
mi_gdb_test "-stack-list-arguments --no-frame-filters 1" \
"\\^done,stack-args=\\\[frame={level=\"0\",args=\\\[{name=\"foo\",value=\"21\"},{name=\"bar\",value=\"$hex \\\\\"Param\\\\\"\"},{name=\"fb\",value=\"$hex\"},{name=\"bf\",value=\"{nothing = $hex \\\\\"Foo Bar\\\\\", f = 42, s = 19}\"}\\\]},frame={level=\"1\",args=\\\[\\\]},frame={level=\"2\",args=\\\[{name=\"j\",value=\"10\"}\\\]},.*frame={level=\"22\",args=\\\[\\\]},frame={level=\"23\",args=\\\[\\\]},.*frame={level=\"26\",args=\\\[{name=\"f\",value=\"3\"},{name=\"d\",value=\"5\"}\\\]},frame={level=\"27\",args=\\\[\\\]}\\\]" \
"stack-list-arguments --no-frame-filters 1"
mi_gdb_test "-stack-list-arguments 1 0 3" \
"\\^done,stack-args=\\\[frame={level=\"0\",args=\\\[{name=\"foo\",value=\"21\"},{name=\"bar\",value=\"$hex \\\\\"Param\\\\\"\"},{name=\"fb\",value=\"$hex\"},{name=\"bf\",value=\"{nothing = $hex \\\\\"Foo Bar\\\\\", f = 42, s = 19}\"}\\\]},frame={level=\"1\",args=\\\[\\\]},frame={level=\"2\",args=\\\[{name=\"j\",value=\"10\"}\\\]},frame={level=\"3\",args=\\\[\\\]}\\\]" \
"stack-list-arguments 1 0 3"
mi_gdb_test "-stack-list-arguments 1 22 27" \
"\\^done,stack-args=\\\[frame={level=\"22\",args=\\\[\\\],children=\\\[frame={level=\"23\",args=\\\[\\\]}\\\]},.*frame={level=\"26\",args=\\\[{name=\"f\",value=\"3\"},{name=\"d\",value=\"5\"}\\\]},frame={level=\"27\",args=\\\[\\\]}\\\]" \
"stack-list-arguments 1 22 27"
mi_gdb_test "-stack-list-arguments 2" \
"\\^done,stack-args=\\\[frame={level=\"0\",args=\\\[{name=\"foo\",type=\"int\",value=\"21\"},{name=\"bar\",type=\"char \\\*\",value=\"$hex \\\\\"Param\\\\\"\"},{name=\"fb\",type=\"foobar \\\*\",value=\"$hex\"},{name=\"bf\",type=\"foobar\"\}\\\]},frame={level=\"1\",args=\\\[\\\]},frame={level=\"2\",args=\\\[{name=\"j\",type=\"int\",value=\"10\"}\\\]},.*frame={level=\"22\",args=\\\[\\\],children=\\\[frame={level=\"23\",args=\\\[\\\]}\\\]},.*frame={level=\"26\",args=\\\[{name=\"f\",type=\"int\",value=\"3\"},{name=\"d\",type=\"int\",value=\"5\"}\\\]},frame={level=\"27\",args=\\\[\\\]}\\\]" \
"stack-list-arguments 2"
mi_gdb_test "-stack-list-arguments --no-frame-filters 2" \
"\\^done,stack-args=\\\[frame={level=\"0\",args=\\\[{name=\"foo\",type=\"int\",value=\"21\"},{name=\"bar\",type=\"char \\\*\",value=\"$hex \\\\\"Param\\\\\"\"},{name=\"fb\",type=\"foobar \\\*\",value=\"$hex\"},{name=\"bf\",type=\"foobar\"}\\\]},frame={level=\"1\",args=\\\[\\\]},frame={level=\"2\",args=\\\[{name=\"j\",type=\"int\",value=\"10\"}\\\]},.*frame={level=\"22\",args=\\\[\\\]},.*frame={level=\"26\",args=\\\[{name=\"f\",type=\"int\",value=\"3\"},{name=\"d\",type=\"int\",value=\"5\"}\\\]},frame={level=\"27\",args=\\\[\\\]}\\\]" \
"stack-list-arguments --no-frame-filters 2"
mi_gdb_test "-stack-list-arguments 2 0 3" \
"\\^done,stack-args=\\\[frame={level=\"0\",args=\\\[{name=\"foo\",type=\"int\",value=\"21\"},{name=\"bar\",type=\"char \\\*\",value=\"$hex \\\\\"Param\\\\\"\"},{name=\"fb\",type=\"foobar \\\*\",value=\"$hex\"},{name=\"bf\",type=\"foobar\"}\\\]},frame={level=\"1\",args=\\\[\\\]},frame={level=\"2\",args=\\\[{name=\"j\",type=\"int\",value=\"10\"}\\\]},frame={level=\"3\",args=\\\[\\\]}\\\]" \
"stack-list-arguments 2 0 3"
mi_gdb_test "-stack-list-arguments 2 22 27" \
"\\^done,stack-args=\\\[frame={level=\"22\",args=\\\[\\\],children=\\\[frame={level=\"23\",args=\\\[\\\]}\\\]},.*frame={level=\"26\",args=\\\[{name=\"f\",type=\"int\",value=\"3\"},{name=\"d\",type=\"int\",value=\"5\"}\\\]},frame={level=\"27\",args=\\\[\\\]}\\\]" \
"stack-list-arguments 2 22 27"
mi_gdb_test "-stack-list-arguments --no-frame-filters 2 22 27" \
"\\^done,stack-args=\\\[frame={level=\"22\",args=\\\[\\\]},frame={level=\"23\",args=\\\[\\\]},.*frame={level=\"26\",args=\\\[{name=\"f\",type=\"int\",value=\"3\"},{name=\"d\",type=\"int\",value=\"5\"}\\\]},frame={level=\"27\",args=\\\[\\\]}\\\]" \
"stack-list-arguments --no-frame-filters 2 22 27"
#stack-list-locals
mi_gdb_test "-stack-list-locals --no-frame-filters 0" \
"\\^done,locals=\\\[name=\"str\",name=\"st2\",name=\"b\",name=\"c\"\\\]" \
"stack-list-locals --no-frame-filters 0"
mi_gdb_test "-stack-list-locals --no-frame-filters 1" \
"\\^done,locals=\\\[{name=\"str\",value=\"$hex \\\\\"The End\\\\\"\"},{name=\"st2\",value=\"$hex \\\\\"Is Near\\\\\"\"},{name=\"b\",value=\"12\"},{name=\"c\",value=\"5\"}\\\]" \
"stack-list-locals --no-frame-filters 1"
mi_gdb_test "-stack-list-locals --no-frame-filters 2" \
"\\^done,locals=\\\[{name=\"str\",type=\"const char \\\*\",value=\"$hex \\\\\"The End\\\\\"\"},{name=\"st2\",type=\"const char \\\*\",value=\"$hex \\\\\"Is Near\\\\\"\"},{name=\"b\",type=\"int\",value=\"12\"},{name=\"c\",type=\"short\",value=\"5\"}\\\]" \
"stack-list-locals --no-frame-filters 2"
mi_gdb_test "-stack-list-locals --no-frame-filters --no-values" \
"\\^done,locals=\\\[name=\"str\",name=\"st2\",name=\"b\",name=\"c\"\\\]" \
"stack-list-locals --no-frame-filters --no-values"
mi_gdb_test "-stack-list-locals --no-frame-filters --all-values" \
"\\^done,locals=\\\[{name=\"str\",value=\"$hex \\\\\"The End\\\\\"\"},{name=\"st2\",value=\"$hex \\\\\"Is Near\\\\\"\"},{name=\"b\",value=\"12\"},{name=\"c\",value=\"5\"}\\\]" \
"stack-list-locals --no-frame-filters --all-values"
mi_gdb_test "-stack-list-locals --no-frame-filters --simple-values" \
"\\^done,locals=\\\[{name=\"str\",type=\"const char \\\*\",value=\"$hex \\\\\"The End\\\\\"\"},{name=\"st2\",type=\"const char \\\*\",value=\"$hex \\\\\"Is Near\\\\\"\"},{name=\"b\",type=\"int\",value=\"12\"},{name=\"c\",type=\"short\",value=\"5\"}\\\]" \
"stack-list-locals --no-frame-filters --simple-values"
mi_gdb_test "-stack-list-locals 0" \
"\\^done,locals=\\\[name=\"str\",name=\"st2\",name=\"b\",name=\"c\"\\\]" \
"stack-list-locals 0"
mi_gdb_test "-stack-list-locals 1" \
"\\^done,locals=\\\[{name=\"str\",value=\"$hex \\\\\"The End\\\\\"\"},{name=\"st2\",value=\"$hex \\\\\"Is Near\\\\\"\"},{name=\"b\",value=\"12\"},{name=\"c\",value=\"5\"}\\\]" \
"stack-list-locals 1"
mi_gdb_test "-stack-list-locals 2" \
"\\^done,locals=\\\[{name=\"str\",type=\"const char \\\*\",value=\"$hex \\\\\"The End\\\\\"\"},{name=\"st2\",type=\"const char \\\*\",value=\"$hex \\\\\"Is Near\\\\\"\"},{name=\"b\",type=\"int\",value=\"12\"},{name=\"c\",type=\"short\",value=\"5\"}\\\]" \
"stack-list-locals 2"
# stack-list-variables
mi_gdb_test "-stack-list-variables --no-frame-filters 0" \
"\\^done,variables=\\\[{name=\"foo\",arg=\"1\"},{name=\"bar\",arg=\"1\"},{name=\"fb\",arg=\"1\"},{name=\"bf\",arg=\"1\"},{name=\"str\"},{name=\"st2\"},{name=\"b\"},{name=\"c\"}\\\]" \
"stack-list-variables --no-frame-filters 0"
mi_gdb_test "-stack-list-variables 0" \
"\\^done,variables=\\\[{name=\"foo\",arg=\"1\"},{name=\"bar\",arg=\"1\"},{name=\"fb\",arg=\"1\"},{name=\"bf\",arg=\"1\"},{name=\"str\"},{name=\"st2\"},{name=\"b\"},{name=\"c\"}\\\]" \
"stack-list-variables 0"

View File

@ -0,0 +1,155 @@
/* This testcase is part of GDB, the GNU debugger.
Copyright 2013 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/>. */
#include <stdlib.h>
void funca(void);
int count = 0;
typedef struct
{
char *nothing;
int f;
short s;
} foobar;
void end_func (int foo, char *bar, foobar *fb, foobar bf)
{
const char *str = "The End";
const char *st2 = "Is Near";
int b = 12;
short c = 5;
{
int d = 15;
int e = 14;
const char *foo = "Inside block";
{
int f = 42;
int g = 19;
const char *bar = "Inside block x2";
{
short h = 9;
h = h +1; /* Inner test breakpoint */
}
}
}
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)
{
foobar fb;
foobar *bf = NULL;
if (count < 10)
{
count++;
funcb(count);
}
fb.nothing = "Foo Bar";
fb.f = 42;
fb.s = 19;
bf = alloca (sizeof (foobar));
bf->nothing = alloca (128);
bf->nothing = "Bar Foo";
bf->f = 24;
bf->s = 91;
end_func(21, "Param", bf, fb);
return;
}
void func1(void)
{
funca();
return;
}
int func2(int f)
{
int c;
const char *elided = "Elided frame";
foobar fb;
foobar *bf = NULL;
fb.nothing = "Elided Foo Bar";
fb.f = 84;
fb.s = 38;
bf = alloca (sizeof (foobar));
bf->nothing = alloca (128);
bf->nothing = "Elided Bar Foo";
bf->f = 48;
bf->s = 182;
func1();
return 1;
}
void func3(int i)
{
func2(i);
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()
{
int z = 32;
int y = 44;
const char *foo1 = "Test";
func5(3,5);
}

View File

@ -0,0 +1,239 @@
# Copyright (C) 2013 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 gdb-python.exp
standard_testfile
# We cannot use prepare_for_testing as we have to set the safe-patch
# to check objfile and progspace printers.
if {[build_executable $testfile.exp $testfile $srcfile debug] == -1} {
return -1
}
# Start with a fresh gdb.
gdb_exit
gdb_start
# Skip all tests if Python scripting is not enabled.
if { [skip_python_tests] } { continue }
# Make the -gdb.py script available to gdb, it is automagically loaded by gdb.
# Care is taken to put it in the same directory as the binary so that
# gdb will find it.
set remote_obj_python_file \
[remote_download \
host ${srcdir}/${subdir}/${testfile}-gdb.py.in \
${subdir}/${testfile}-gdb.py]
gdb_reinitialize_dir $srcdir/$subdir
gdb_test_no_output "set auto-load safe-path ${remote_obj_python_file}" \
"set auto-load safe-path"
gdb_load ${binfile}
# Verify gdb loaded the script.
gdb_test "info auto-load python-scripts" "Yes.*/${testfile}-gdb.py.*" \
"Test auto-load had loaded python scripts"
if ![runto_main] then {
perror "couldn't run to breakpoint"
return
}
gdb_test_no_output "set python print-stack full" \
"Set python print-stack to full"
# Load global frame-filters
set remote_python_file [remote_download host ${srcdir}/${subdir}/${testfile}.py]
gdb_test_no_output "python execfile ('${remote_python_file}')" \
"Load python file"
gdb_breakpoint [gdb_get_line_number "Backtrace end breakpoint"]
gdb_breakpoint [gdb_get_line_number "Inner test breakpoint"]
gdb_continue_to_breakpoint "Inner test breakpoint"
# Test multiple local blocks.
gdb_test "bt full no-filters" \
".*#0.*end_func.*h = 9.*f = 42.*g = 19.*bar = $hex \"Inside block x2\".*d = 15.*e = 14.*foo = $hex \"Inside block\".*str = $hex \"The End\".*st2 = $hex \"Is Near\".*b = 12.*c = 5.*" \
"bt full no-filters"
gdb_test "bt full" \
".*#0.*cnuf_dne.*h = 9.*f = 42.*g = 19.*bar = $hex \"Inside block x2\".*d = 15.*e = 14.*foo = $hex \"Inside block\".*str = $hex \"The End\".*st2 = $hex \"Is Near\".*b = 12.*c = 5.*" \
"bt full with filters"
gdb_continue_to_breakpoint "Backtrace end breakpoint"
# Test set/show
gdb_test "info frame-filter" \
".*900.*Yes.*Elider.*100.*Yes.*Reverse.*10.*.*No.*Object.*1.*" \
"info frame filter before setting priority"
gdb_test "show frame-filter priority global Elider" \
"Priority of filter 'Elider' in list 'global' is: 900" \
"show frame-filter priority global Elider before setting"
gdb_test_no_output "set frame-filter priority global Elider 1000" \
"set frame-filter priotiy global Elider 1000"
gdb_test "show frame-filter priority global Elider" \
"Priority of filter 'Elider' in list 'global' is: 1000" \
"show frame-filter priority global Elider after setting"
gdb_test "info frame-filter" \
".*1000.*Yes.*Elider.*100.*Yes.*Reverse.*10.*.*No.*Object.*1.*" \
"info frame filter after setting priority"
# Test enable/disable
gdb_test "info frame-filter" \
".*1000.*Yes.*Elider.*100.*Yes.*Reverse.*10.*.*No.*Object.*1.*" \
"info frame filter before disable frame filter"
gdb_test_no_output "disable frame-filter global Elider" \
"disable frame-filter global Elider"
gdb_test "info frame-filter" \
".*1000.*No.*Elider.*100.*Yes.*Reverse.*10.*.*No.*Object.*1.*" \
"info frame filter after disable frame filter"
gdb_test_no_output "enable frame-filter global Elider" \
"enable frame-filter global Elider"
gdb_test "info frame-filter" \
".*1000.*Yes.*Elider.*100.*Yes.*Reverse.*10.*.*No.*Object.*1.*" \
"info frame filter after reenabling frame filter"
# Test no-filters
gdb_test "bt no-filters" \
".*#0.*end_func.*#22.*in func1.*#27.*in main \\(\\).*" \
"bt no-filters"
# Test reverse
gdb_test "bt" \
".*#0.*cnuf_dne.*#22.*in 1cnuf.*#27.*in niam \\(\\).*" \
"bt with frame filters"
# Disable Reverse
gdb_test_no_output "disable frame-filter global Reverse" \
"disable frame-filter global Reverse"
gdb_test "bt" \
".*#0.*end_func.*#22.*in func1.*#27.*in main \\(\\).*" \
"bt with frame-filter Reverse disabled"
gdb_test "bt -2" \
".*#26.*func5.*#27.*in main \\(\\).*" \
"bt -2 with frame-filter Reverse disabled"
gdb_test "bt 3" \
".*#0.*end_func.*#1.*in funca \\(\\).*#2.*in funcb \\(j=10\\).*" \
"bt 3 with frame-filter Reverse disabled"
gdb_test "bt no-filter full" \
".*#0.*end_func.*str = $hex \"The End\".*st2 = $hex \"Is Near\".*b = 12.*c = 5.*#1.*in funca \\(\\).*#2.*in funcb \\(j=10\\).*bar = \{a = 42, b = 84\}.*" \
"bt no-filters full with Reverse disabled"
gdb_test "bt full" \
".*#0.*end_func.*str = $hex \"The End\".*st2 = $hex \"Is Near\".*b = 12.*c = 5.*#1.*in funca \\(\\).*#2.*in funcb \\(j=10\\).*bar = \{a = 42, b = 84\}.*#22.*in func1 \\(\\).*#23.*in func2 \\(f=3\\).*elided = $hex \"Elided frame\".*fb = \{nothing = $hex \"Elided Foo Bar\", f = 84, s = 38\}.*bf = $hex.*" \
"bt full with Reverse disabled"
# Test set print frame-arguments
# none
gdb_test_no_output "set print frame-arguments none" \
"turn off frame arguments"
gdb_test "bt no-filter 1" \
"#0.*end_func \\(foo=\.\.\., bar=\.\.\., fb=\.\.\., bf=\.\.\.\\) at .*py-framefilter.c.*" \
"bt no-filter 1 no args"
gdb_test "bt 1" \
"#0.*end_func \\(foo=\.\.\., bar=\.\.\., fb=\.\.\., bf=\.\.\.\\) at .*py-framefilter.c.*" \
"bt 1 no args"
# scalars
gdb_test_no_output "set print frame-arguments scalars" \
"turn frame arguments to scalars only"
gdb_test "bt no-filter 1" \
"#0.*end_func \\(foo=21, bar=$hex \"Param\", fb=$hex, bf=\.\.\.\\) at .*py-framefilter.c.*" \
"bt no-filter 1 scalars"
gdb_test "bt 1" \
"#0.*end_func \\(foo=21, bar=$hex \"Param\", fb=$hex, bf=\.\.\.\\) at .*py-framefilter.c.*" \
"bt 1 scalars"
# all
gdb_test_no_output "set print frame-arguments all" \
"turn on frame arguments"
gdb_test "bt no-filter 1" \
"#0.*end_func \\(foo=21, bar=$hex \"Param\", fb=$hex, bf=\{nothing = $hex \"Foo Bar\", f = 42, s = 19\}\\) at .*py-framefilter.c.*" \
"bt no-filter 1 all args"
gdb_test "bt 1" \
"#0.*end_func \\(foo=21, bar=$hex \"Param\", fb=$hex, bf=\{nothing = $hex \"Foo Bar\", f = 42, s = 19\}\\) at .*py-framefilter.c.*" \
"bt 1 all args"
# set print address off
gdb_test_no_output "set print address off" \
"Turn off address printing"
gdb_test "bt no-filter 1" \
"#0 end_func \\(foo=21, bar=\"Param\", fb=, bf=\{nothing = \"Foo Bar\", f = 42, s = 19\}\\) at .*py-framefilter.c.*" \
"bt no-filter 1 no address"
gdb_test "bt 1" \
"#0 end_func \\(foo=21, bar=\"Param\", fb=, bf=\{nothing = \"Foo Bar\", f = 42, s = 19\}\\) at .*py-framefilter.c.*" \
"bt 1 no addresss"
remote_file host delete ${remote_python_file}
# Test with no debuginfo
# We cannot use prepare_for_testing as we have to set the safe-patch
# to check objfile and progspace printers.
if {[build_executable $testfile.exp $testfile $srcfile {nodebug}] == -1} {
return -1
}
# Start with a fresh gdb.
gdb_exit
gdb_start
# Skip all tests if Python scripting is not enabled.
if { [skip_python_tests] } { continue }
# Make the -gdb.py script available to gdb, it is automagically loaded by gdb.
# Care is taken to put it in the same directory as the binary so that
# gdb will find it.
set remote_obj_python_file \
[remote_download \
host ${srcdir}/${subdir}/${testfile}-gdb.py.in \
${subdir}/${testfile}-gdb.py]
gdb_reinitialize_dir $srcdir/$subdir
gdb_test_no_output "set auto-load safe-path ${remote_obj_python_file}" \
"set auto-load safe-path for no debug info"
gdb_load ${binfile}
# Verify gdb loaded the script.
gdb_test "info auto-load python-scripts" "Yes.*/${testfile}-gdb.py.*" \
"Set autoload path for no debug info tests"
if ![runto_main] then {
perror "couldn't run to breakpoint"
return
}
gdb_test_no_output "set python print-stack full" \
"set python print-stack full for no debuginfo tests"
# Load global frame-filters
set remote_python_file [remote_download host ${srcdir}/${subdir}/${testfile}.py]
gdb_test_no_output "python execfile ('${remote_python_file}')" \
"Load python file for no debuginfo tests"
# Disable Reverse
gdb_test_no_output "disable frame-filter global Reverse" \
"disable frame-filter gloval Reverse for no debuginfo"
gdb_test "bt" \
".*#0..*in main \\(\\).*" \
"bt for no debuginfo"
gdb_test "bt full" \
".*#0..*in main \\(\\).*" \
"bt full for no debuginfo"
gdb_test "bt no-filters" \
".*#0..*in main \\(\\).*" \
"bt no filters for no debuginfo"
gdb_test "bt no-filters full" \
".*#0..*in main \\(\\).*" \
"bt no-filters full no debuginfo"

View File

@ -0,0 +1,117 @@
# Copyright (C) 2013 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.
import gdb
import itertools
from gdb.FrameDecorator import FrameDecorator
import copy
class Reverse_Function (FrameDecorator):
def __init__(self, fobj):
super(Reverse_Function, self).__init__(fobj)
self.fobj = fobj
def function (self):
fname = str (self.fobj.function())
if (fname == None or fname == ""):
return None
else:
fname = fname[::-1]
return fname
class Dummy (FrameDecorator):
def __init__(self, fobj):
super(Dummy, self).__init__(fobj)
self.fobj = fobj
def function (self):
return "Dummy function"
def address (self):
return 0x123
def filename (self):
return "Dummy filename"
def frame_args (self):
return [("Foo",gdb.Value(12)),("Bar","Stuff"), ("FooBar",42)]
def frame_locals (self):
return []
def line (self):
return 0
def elided (self):
return None
class FrameFilter ():
def __init__ (self):
self.name = "Reverse"
self.priority = 100
self.enabled = True
gdb.frame_filters [self.name] = self
def filter (self, frame_iter):
frame_iter = itertools.imap (Reverse_Function,
frame_iter)
return frame_iter
class ElidingFrameDecorator(FrameDecorator):
def __init__(self, frame, elided_frames):
super(ElidingFrameDecorator, self).__init__(frame)
self.elided_frames = elided_frames
def elided(self):
return iter(self.elided_frames)
class ElidingIterator:
def __init__(self, ii):
self.input_iterator = ii
def __iter__(self):
return self
def next(self):
frame = next(self.input_iterator)
if str(frame.function()) != 'func1':
return frame
# Suppose we want to return the 'func1' frame but elide the
# next frame. E.g., if call in our interpreter language takes
# two C frames to implement, and the first one we see is the
# "sentinel".
elided = next(self.input_iterator)
return ElidingFrameDecorator(frame, [elided])
class FrameElider ():
def __init__ (self):
self.name = "Elider"
self.priority = 900
self.enabled = True
gdb.frame_filters [self.name] = self
def filter (self, frame_iter):
return ElidingIterator (frame_iter)
FrameFilter()
FrameElider()