From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 20098 invoked by alias); 18 Feb 2013 14:29:14 -0000 Mailing-List: contact archer-commits-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: Received: (qmail 20042 invoked by uid 9514); 18 Feb 2013 14:29:13 -0000 Date: Mon, 18 Feb 2013 14:29:00 -0000 Message-ID: <20130218142913.20027.qmail@sourceware.org> From: pmuldoon@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] archer-pmuldoon-python-backtrace: Tom Tromey's FSF GDB review changes, part 1 X-Git-Refname: refs/heads/archer-pmuldoon-python-backtrace X-Git-Reftype: branch X-Git-Oldrev: 5375ed953a4c655b29e57a11087d1c1cead7aa76 X-Git-Newrev: a66b32b2338f9ae4675354eb00b0bbb61a1cf6a5 X-SW-Source: 2013-q1/txt/msg00047.txt.bz2 List-Id: The branch, archer-pmuldoon-python-backtrace has been updated via a66b32b2338f9ae4675354eb00b0bbb61a1cf6a5 (commit) from 5375ed953a4c655b29e57a11087d1c1cead7aa76 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit a66b32b2338f9ae4675354eb00b0bbb61a1cf6a5 Author: Phil Muldoon Date: Mon Feb 18 14:27:40 2013 +0000 Tom Tromey's FSF GDB review changes, part 1 ----------------------------------------------------------------------- Summary of changes: gdb/data-directory/Makefile.in | 1 - gdb/mi/mi-cmd-stack.c | 42 +- gdb/mi/mi-getopt.c | 10 +- gdb/python/lib/gdb/BaseFrameWrapper.py | 293 ------- gdb/python/lib/gdb/FrameIterator.py | 6 +- gdb/python/lib/gdb/FrameWrapper.py | 400 +++++++---- gdb/python/lib/gdb/command/frame_filters.py | 265 +++---- gdb/python/py-framefilter.c | 863 +++++++++++---------- gdb/python/python.h | 31 +- gdb/stack.c | 11 +- gdb/testsuite/gdb.python/py-framefilter-gdb.py.in | 14 +- gdb/testsuite/gdb.python/py-framefilter.py | 10 +- 12 files changed, 951 insertions(+), 995 deletions(-) delete mode 100644 gdb/python/lib/gdb/BaseFrameWrapper.py First 500 lines of diff: diff --git a/gdb/data-directory/Makefile.in b/gdb/data-directory/Makefile.in index 5f91bfb..95e40a8 100644 --- a/gdb/data-directory/Makefile.in +++ b/gdb/data-directory/Makefile.in @@ -53,7 +53,6 @@ PYTHON_DIR = python PYTHON_INSTALL_DIR = $(DESTDIR)$(GDB_DATADIR)/$(PYTHON_DIR) PYTHON_FILES = \ gdb/__init__.py \ - gdb/BaseFrameWrapper.py \ gdb/FrameIterator.py \ gdb/FrameWrapper.py \ gdb/types.py \ diff --git a/gdb/mi/mi-cmd-stack.c b/gdb/mi/mi-cmd-stack.c index bae0b09..82d92d7 100644 --- a/gdb/mi/mi-cmd-stack.c +++ b/gdb/mi/mi-cmd-stack.c @@ -32,6 +32,7 @@ #include "valprint.h" #include "exceptions.h" #include "utils.h" +#include "mi-getopt.h" #include "python/python.h" #include enum what_to_list { locals, arguments, all }; @@ -74,10 +75,33 @@ mi_cmd_stack_list_frames (char *command, char **argv, int argc) struct frame_info *fi; int result = 0; int raw_arg = 0; + enum opt + { + NO_FRAME_FILTERS + }; + static const struct mi_opt opts[] = + { + {"no-frame-filters", NO_FRAME_FILTERS, 0}, + { 0, 0, 0 } + }; - if (argc > 0) - raw_arg = parse_no_frames_option (argv[0]); - + /* Parse arguments. In this instance we are just looking for + --no-frame-filters. */ + while (1) + { + int oind = 0; + char *oarg; + int opt = mi_getopt ("-stack-list-frames", argc, argv, + opts, &oind, &oarg); + if (opt < 0) + break; + switch ((enum opt) opt) + { + case NO_FRAME_FILTERS: + raw_arg = 1; + break; + } + } if ((argc > 3 && ! raw_arg) || (argc == 1 && ! raw_arg) || (argc == 2 && raw_arg)) error (_("-stack-list-frames: Usage: [--no-frame-filters] [FRAME_LOW FRAME_HIGH]")); @@ -115,7 +139,7 @@ mi_cmd_stack_list_frames (char *command, char **argv, int argc) if (frame_high != -1) count = (frame_high - frame_low) + 1; - result = apply_frame_filter (fi, flags, 0, NULL, current_uiout, + result = apply_frame_filter (fi, flags, NO_VALUES, current_uiout, count); } @@ -204,15 +228,15 @@ mi_cmd_stack_list_locals (char *command, char **argv, int argc) || (argc == 1 && raw_arg)) error (_("-stack-list-locals: Usage: [--no-frame-filters] PRINT_VALUES")); - frame = get_selected_frame (NULL); - print_value = parse_print_values (argv[raw_arg]); + frame = get_selected_frame (NULL); + print_value = parse_print_values (argv[raw_arg]); if (! raw_arg && frame_filters) { int flags = PRINT_LEVEL | PRINT_LOCALS; result = apply_frame_filter (frame, flags, print_value, - NULL, current_uiout, 1); + current_uiout, 1); } if (! frame_filters || raw_arg || result == PY_BT_ERROR @@ -282,7 +306,7 @@ mi_cmd_stack_list_args (char *command, char **argv, int argc) if (frame_high != -1) count = (frame_high - frame_low) + 1; - result = apply_frame_filter (fi, flags, print_values, NULL, + result = apply_frame_filter (fi, flags, print_values, current_uiout, count); } @@ -336,7 +360,7 @@ mi_cmd_stack_list_variables (char *command, char **argv, int argc) { int flags = PRINT_LEVEL | PRINT_ARGS | PRINT_LOCALS; - result = apply_frame_filter (frame, flags, print_value, NULL, + result = apply_frame_filter (frame, flags, print_value, current_uiout, 1); } diff --git a/gdb/mi/mi-getopt.c b/gdb/mi/mi-getopt.c index a1e2ccc..be76ac1 100644 --- a/gdb/mi/mi-getopt.c +++ b/gdb/mi/mi-getopt.c @@ -29,6 +29,7 @@ mi_getopt (const char *prefix, { char *arg; const struct mi_opt *opt; + int olength = 1; /* We assume that argv/argc are ok. */ if (*oind > argc || *oind < 0) @@ -50,10 +51,15 @@ mi_getopt (const char *prefix, *oarg = NULL; return -1; } + + /* Deal with --foo options. */ + if (arg[0] == '-' && arg[1] == '-') + olength++; + /* Look the option up. */ for (opt = opts; opt->name != NULL; opt++) { - if (strcmp (opt->name, arg + 1) != 0) + if (strcmp (opt->name, arg + olength) != 0) continue; if (opt->arg_p) { @@ -71,7 +77,7 @@ mi_getopt (const char *prefix, return opt->index; } } - error (_("%s: Unknown option ``%s''"), prefix, arg + 1); + error (_("%s: Unknown option ``%s''"), prefix, arg + olength); } int diff --git a/gdb/python/lib/gdb/BaseFrameWrapper.py b/gdb/python/lib/gdb/BaseFrameWrapper.py deleted file mode 100644 index c96a7df..0000000 --- a/gdb/python/lib/gdb/BaseFrameWrapper.py +++ /dev/null @@ -1,293 +0,0 @@ -# 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 . - -import gdb -from gdb.FrameWrapper import FrameWrapper - -class BaseFrameWrapper(FrameWrapper): - """Basic implementation of a Frame Wrapper""" - - """ This base frame wrapper wraps a frame or another frame - wrapper, and provides convenience methods. If this object is - wrapping a frame wrapper, defer to that wrapped object's method if - it has one. This allows for frame wrappers that have sub-classed - BaseFrameWrapper, but also wrap other frame wrappers on the same - frame to correctly execute. - - E.g - - If the result of frame filters running means we have one gdb.Frame - wrapped by multiple frame wrappers, all sub-classed from - BaseFrameWrapper: - - Wrapper1(Wrapper2(BaseFrameWrapper(gdb.Frame))) - - In this case we have two frame wrappers, both of which are - sub-classed from BaseFrameWrapper. If Wrapper1 just overrides the - 'function' method, then all of the other methods are carried out - by the super-class BaseFrameWrapper. But Wrapper2 may have - overriden other methods, so BaseFrameWrapper will look at the - 'base' parameter and defer to that class's methods. And so on, - down the chain.""" - - # 'base' can refer to a gdb.Frame or another frame filter. In - # the latter case, the child class will have called the super - # method and base will be an object conforming to the Frame Filter - # class. - def __init__(self, base): - super(BaseFrameWrapper, self).__init__(base) - self.base = base - - @staticmethod - def is_limited_frame(frame): - """Internal utility to determine if the frame is special or - limited.""" - sal = frame.find_sal() - - if (not sal.symtab or not sal.symtab.filename - or frame == gdb.DUMMY_FRAME - or frame == gdb.SIGTRAMP_FRAME): - - return True - - return False - - def elided(self): - """Return any elided frames that this class might be - wrapping, or None.""" - if hasattr(self.base, "elided"): - return self.base.elided() - - return None - - def function(self): - """ Return the name of the frame's function, first determining - if it is a special frame. If not, try to determine filename - from GDB's frame internal function API. Finally, if a name - cannot be determined return the address.""" - - if not isinstance(self.base, gdb.Frame): - if hasattr(self.base, "function"): - return self.base.function() - - frame = self.inferior_frame() - - if frame.type() == gdb.DUMMY_FRAME: - return "" - elif frame.type() == gdb.SIGTRAMP_FRAME: - return "" - - func = frame.function() - sal = frame.find_sal() - pc = frame.pc() - - if func == None: - unknown = format(" 0x%08x in" % pc) - return unknown - - return str(func) - - def address(self): - """ Return the address of the frame's pc""" - - if hasattr(self.base, "address"): - return self.base.address() - - frame = self.inferior_frame() - return frame.pc() - - def filename(self): - """ Return the filename associated with this frame, detecting - and returning the appropriate library name is this is a shared - library.""" - - if hasattr(self.base, "filename"): - return self.base.filename() - - frame = self.inferior_frame() - sal = frame.find_sal() - if (not sal.symtab or not sal.symtab.filename): - pc = frame.pc() - return gdb.solib_name(pc) - else: - return sal.symtab.filename - - def frame_args(self): - """ Return an iterator of frame arguments for this frame, if - any. The iterator contains objects conforming with the - Symbol/Value interface. If there are no frame arguments, or - if this frame is deemed to be a special case, return None.""" - - if hasattr(self.base, "frame_args"): - return self.base.frame_args() - - frame = self.inferior_frame() - if self.is_limited_frame(frame): - return None - - args = FrameVars(frame) - return args.fetch_frame_args() - - def frame_locals(self): - """ Return an iterator of local variables for this frame, if - any. The iterator contains objects conforming with the - Symbol/Value interface. If there are no frame locals, or if - this frame is deemed to be a special case, return None.""" - - if hasattr(self.base, "frame_locals"): - return self.base.frame_locals() - - frame = self.inferior_frame() - if self.is_limited_frame(frame): - return None - - args = FrameVars(frame) - return args.fetch_frame_locals() - - def line(self): - """ Return line number information associated with the frame's - pc. If symbol table/line information does not exist, or if - this frame is deemed to be a special case, return None""" - - if hasattr(self.base, "line"): - return self.base.line() - - frame = self.inferior_frame() - if self.is_limited_frame(frame): - return None - - sal = frame.find_sal() - if (sal): - return sal.line - else: - return None - - def inferior_frame(self): - """ Return the gdb.Frame underpinning this frame wrapper.""" - - # If 'base' is a frame wrapper, we want to call its inferior - # frame method. If 'base' is a gdb.Frame, just return that. - if hasattr(self.base, "inferior_frame"): - return self.base.inferior_frame() - return self.base - -class BaseSymValueWrapper(): - """A container class conforming to the Symbol/Value interface - which holds frame locals or frame arguments.""" - def __init__(self, symbol, value): - self.sym = symbol - self.val = value - - def value(self): - """ Return the value associated with this symbol, or None""" - return self.val - - def symbol(self): - """ Return the symbol, or Python text, associated with this - symbol, or None""" - return self.sym - -class FrameVars(): - - """Utility class to fetch and store frame local variables, or - frame arguments.""" - - def __init__(self,frame): - self.frame = frame - - @staticmethod - def fetch_b(sym): - """ Local utility method to determine if according to Symbol - type whether it should be included in the iterator. Not all - symbols are fetched, and only symbols that return - True from this method should be fetched.""" - - # SYM may be a string instead of a symbol in the case of - # synthetic local arguments or locals. If that is the case, - # always fetch. - if isinstance(sym, basestring): - return True - - sym_type = sym.addr_class - - return { - gdb.SYMBOL_LOC_STATIC: True, - gdb.SYMBOL_LOC_REGISTER: True, - gdb.SYMBOL_LOC_ARG: True, - gdb.SYMBOL_LOC_REF_ARG: True, - gdb.SYMBOL_LOC_LOCAL: True, - gdb.SYMBOL_LOC_REGPARM_ADDR: True, - gdb.SYMBOL_LOC_COMPUTED: True - }.get(sym_type, False) - - def fetch_frame_locals(self): - """Public utility method to fetch frame local variables for - the stored frame. Frame arguments are not fetched. If there - are not frame local variables, return None.""" - lvars = [] - try: - block = self.frame.block() - except: - return None - - for sym in block: - if sym.is_argument: - continue; - if self.fetch_b(sym): - lvars.append(BaseSymValueWrapper(sym, None)) - - if len(lvars) == 0: - return None - - return iter(lvars) - - def fetch_frame_args(self): - """Public utility method to fetch frame argument for the - stored frame. Frame arguments are the only type fetched. If - there are no frame arguments variables, return None.""" - - args = [] - try: - block = self.frame.block() - except: - return None - - for sym in block: - if not sym.is_argument: - continue; - args.append(BaseSymValueWrapper(sym,None)) - - if len(args) == 0: - return None - - return iter(args) - - def get_value(self, sym, block): - """Public utility method to fetch a value from a symbol.""" - if len(sym.linkage_name): - nsym, is_field_of_this = gdb.lookup_symbol(sym.linkage_name, block) - if nsym != None: - if nsym.addr_class != gdb.SYMBOL_LOC_REGISTER: - sym = nsym - - try: - val = sym.value(self.frame) - - except RuntimeError, text: - val = text - if val == None: - val = "???" - - return val diff --git a/gdb/python/lib/gdb/FrameIterator.py b/gdb/python/lib/gdb/FrameIterator.py index ddc9087..636e778 100644 --- a/gdb/python/lib/gdb/FrameIterator.py +++ b/gdb/python/lib/gdb/FrameIterator.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012 Free Software Foundation, Inc. +# Copyright (C) 2012, 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 @@ -41,7 +41,7 @@ class FrameIterator(object): return next(itertools.islice(self.frame,index,index+1)) def next (self): - """__next__ implementation. + """next implementation. Returns: The next oldest frame.""" @@ -49,5 +49,5 @@ class FrameIterator(object): result = self.frame if result is None: raise StopIteration - self.frame = result.older () + self.frame = result.older() return result diff --git a/gdb/python/lib/gdb/FrameWrapper.py b/gdb/python/lib/gdb/FrameWrapper.py index 4db9a43..acdd84c 100644 --- a/gdb/python/lib/gdb/FrameWrapper.py +++ b/gdb/python/lib/gdb/FrameWrapper.py @@ -1,4 +1,4 @@ -# Copyright (C) 2012 Free Software Foundation, Inc. +# Copyright (C) 2012, 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 @@ -15,141 +15,271 @@ import gdb -class FrameWrapper (object): - """Interface for a Frame Wrapper.""" +class FrameWrapper(object): + """Basic implementation of a Frame Wrapper""" - """ A frame wrapper wraps a frame and provides additional and - convenience methods. """ - def __init__(self, frame): - super(FrameWrapper, self).__init__() - self.frame = frame + """ This base frame wrapper wraps a frame or another frame + wrapper, and provides convenience methods. If this object is + wrapping a frame wrapper, defer to that wrapped object's method if + it has one. This allows for frame wrappers that have sub-classed + FrameWrapper, but also wrap other frame wrappers on the same + frame to correctly execute. hooks/post-receive -- Repository for Project Archer.