From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 6644 invoked by alias); 8 Mar 2013 14:24:56 -0000 Mailing-List: contact archer-commits-help@sourceware.org; run by ezmlm Sender: Precedence: bulk List-Post: List-Help: List-Subscribe: Received: (qmail 6608 invoked by uid 9514); 8 Mar 2013 14:24:53 -0000 Date: Fri, 08 Mar 2013 14:24:00 -0000 Message-ID: <20130308142453.6593.qmail@sourceware.org> From: pmuldoon@sourceware.org To: archer-commits@sourceware.org Subject: [SCM] pmuldoon/python-backtrace: Rename FrameWrapper to FrameDecorator. Adjust Tom Tromey's comments to gdb manaual. Fix some missed review comments. X-Git-Refname: refs/heads/pmuldoon/python-backtrace X-Git-Reftype: branch X-Git-Oldrev: 6be7cc274c29aed33191c0f38f33b33b6322450a X-Git-Newrev: 2df7735feedd77ddc69ea7d486135eecfa268c6e X-SW-Source: 2013-q1/txt/msg00247.txt.bz2 List-Id: The branch, pmuldoon/python-backtrace has been updated via 2df7735feedd77ddc69ea7d486135eecfa268c6e (commit) from 6be7cc274c29aed33191c0f38f33b33b6322450a (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email. - Log ----------------------------------------------------------------- commit 2df7735feedd77ddc69ea7d486135eecfa268c6e Author: Phil Muldoon Date: Fri Mar 8 14:24:08 2013 +0000 Rename FrameWrapper to FrameDecorator. Adjust Tom Tromey's comments to gdb manaual. Fix some missed review comments. ----------------------------------------------------------------------- Summary of changes: gdb/data-directory/Makefile.in | 2 +- gdb/doc/gdb.texinfo | 622 ++++++++++---------- gdb/mi/mi-cmd-stack.c | 6 +- gdb/mi/mi-cmd-var.c | 9 - .../lib/gdb/{FrameWrapper.py => FrameDecorator.py} | 41 +- gdb/python/lib/gdb/command/frame_filters.py | 2 +- gdb/python/lib/gdb/frames.py | 6 +- gdb/testsuite/gdb.python/py-framefilter-gdb.py.in | 2 +- gdb/testsuite/gdb.python/py-framefilter.exp | 17 +- gdb/testsuite/gdb.python/py-framefilter.py | 12 +- 10 files changed, 362 insertions(+), 357 deletions(-) rename gdb/python/lib/gdb/{FrameWrapper.py => FrameDecorator.py} (87%) First 500 lines of diff: diff --git a/gdb/data-directory/Makefile.in b/gdb/data-directory/Makefile.in index 88634a6..13433ed 100644 --- a/gdb/data-directory/Makefile.in +++ b/gdb/data-directory/Makefile.in @@ -55,7 +55,7 @@ PYTHON_FILES = \ gdb/__init__.py \ gdb/frames.py \ gdb/FrameIterator.py \ - gdb/FrameWrapper.py \ + gdb/FrameDecorator.py \ gdb/types.py \ gdb/printing.py \ gdb/prompt.py \ diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo index c996671..8bfc579 100644 --- a/gdb/doc/gdb.texinfo +++ b/gdb/doc/gdb.texinfo @@ -6291,6 +6291,7 @@ currently executing frame and describes it briefly, similar to the @menu * Frames:: Stack frames * Backtrace:: Backtraces +* Frame Filter Management:: Managing frame filters * Selection:: Selecting a frame * Frame Info:: Information on a frame @@ -6413,7 +6414,7 @@ number of frames to print, as described above. @itemx bt no-filters full @var{n} @itemx bt no-filters full -@var{n} Do not run Python frame filters on this backtrace. @xref{Frame -Filters API}, for more information. Additionally use @ref{disable +Filter API}, for more information. Additionally use @ref{disable frame-filter all} to turn off all frame filters. This is only relevant when @value{GDBN} has been configured with @code{Python} support. @@ -6566,6 +6567,146 @@ Display an absolute filename. Show the current way to display filenames. @end table +@node Frame Filter Management +@section Management of Frame Filters. +@cindex managing frame filters + +There are several commands available within @value{GDBN} to manage +frame filters, detailed here. + +@table @code +@kindex info frame-filter +@item info frame-filter +Print a list of installed frame filters from all dictionaries, showing +their name, priority and enabled status. + +@kindex disable frame-filter +@anchor{disable frame-filter all} +@item disable frame-filter @var{filter-dictionary} @var{filter-name} +Disable a frame filter in the dictionary matching +@var{filter-dictionary}, or @code{all}, and @var{filter-name}. +@var{filter-dictionary} may be @code{all}, @code{global}, +@code{progspace} or the name of the object file where the frame filter +dictionary resides. When @code{all} is specified, all frame filters +across all dictionaries are disabled. @var{filter-name} is the name +of the frame filter and is used when @code{all} is not the option for +@var{filter-dictionary}. A disabled frame-filter is not deleted, it +may be enabled again later. + +@kindex enable frame-filter +@item enable frame-filter @var{filter-dictionary} @var{filter-name} +Enable a frame filter in the dictionary matching +@var{filter-dictionary}, or @code{all}, and @var{filter-name}. +@var{filter-dictionary} may be @code{all}, @code{global}, +@code{progspace} or the name of the object file where the frame filter +dictionary resides. When @code{all} is specified, all frame filters across +all dictionaries are enabled. @var{filter-name} is the name of the frame +filter and is used when @code{all} is not the option for +@var{filter-dictionary}. + +Example: + +@smallexample +(gdb) info frame-filter + +global frame-filters: + Priority Enabled Name + 1000 No PrimaryFunctionFilter + 100 Yes Reverse + +progspace /build/test frame-filters: + Priority Enabled Name + 100 Yes ProgspaceFilter + +objfile /build/test frame-filters: + Priority Enabled Name + 999 Yes BuildProgra Filter + +(gdb) disable frame-filter /build/test BuildProgramFilter +(gdb) info frame-filter + +global frame-filters: + Priority Enabled Name + 1000 No PrimaryFunctionFilter + 100 Yes Reverse + +progspace /build/test frame-filters: + Priority Enabled Name + 100 Yes ProgspaceFilter + +objfile /build/test frame-filters: + Priority Enabled Name + 999 No BuildProgramFilter + +(gdb) enable frame-filter global PrimaryFunctionFilter +(gdb) info frame-filter + +global frame-filters: + Priority Enabled Name + 1000 Yes PrimaryFunctionFilter + 100 Yes Reverse + +progspace /build/test frame-filters: + Priority Enabled Name + 100 Yes ProgspaceFilter + +objfile /build/test frame-filters: + Priority Enabled Name + 999 No BuildProgramFilter +@end smallexample + +@kindex set python frame-filter priority +@item set python frame-filter priority @var{filter-dictionary} @var{filter-name} @var{priority} +Set the @var{priority} of a frame filter in the dictionary matching +@var{filter-dictionary}, and the frame filter name matching +@var{filter-name}. @var{filter-dictionary} may be @code{global}, +@code{progspace} or the name of the object file where the frame filter +dictionary resides. @var{priority} is an integer. + +@kindex show python frame-filter priority +@item show python frame-filter priority @var{filter-dictionary} @var{filter-name} +Show the @var{priority} of a frame filter in the dictionary matching +@var{filter-dictionary}, and the frame filter name matching +@var{filter-name}. @var{filter-dictionary} may be @code{global}, +@code{progspace} or the name of the object file where the frame filter +dictionary resides. + +Example: + +@smallexample +(gdb) info frame-filter + +global frame-filters: + Priority Enabled Name + 1000 Yes PrimaryFunctionFilter + 100 Yes Reverse + +progspace /build/test frame-filters: + Priority Enabled Name + 100 Yes ProgspaceFilter + +objfile /build/test frame-filters: + Priority Enabled Name + 999 No BuildProgramFilter + +(gdb) set python frame-filter priority global Reverse 50 +(gdb) info frame-filter + +global frame-filters: + Priority Enabled Name + 1000 Yes PrimaryFunctionFilter + 50 Yes Reverse + +progspace /build/test frame-filters: + Priority Enabled Name + 100 Yes ProgspaceFilter + +objfile /build/test frame-filters: + Priority Enabled Name + 999 No BuildProgramFilter +@end smallexample +@end table + @node Selection @section Selecting a Frame @@ -22852,10 +22993,9 @@ situation, a Python @code{KeyboardInterrupt} exception is thrown. * Selecting Pretty-Printers:: How GDB chooses a pretty-printer. * Writing a Pretty-Printer:: Writing a Pretty-Printer. * Type Printing API:: Pretty-printing types. -* Frame Filters API:: Filtering and Wrapping Frames. -* Frame Wrapper API:: Wrapping and Decorating Frames. -* Writing a Frame Filter/Wrapper:: Writing a Frame Filter and Wrapper. -* Managing Frame Filters:: Management of Frame Filters. +* Frame Filter API:: Filtering Frames. +* Frame Decorator API:: Decorating Frames. +* Writing a Frame Filter/Decorator:: Writing a Frame Filter and Decorator. * Inferiors In Python:: Python representation of inferiors (processes) * Events In Python:: Listening for events from @value{GDBN}. * Threads In Python:: Accessing inferior threads from Python. @@ -24206,8 +24346,8 @@ done then type printers would have to make use of the event system in order to avoid holding information that could become stale as the inferior changed. -@node Frame Filters API -@subsubsection Filtering and Wrapping Frames. +@node Frame Filter API +@subsubsection Filtering Frames. @cindex frame filters api Frame filters are Python objects that manipulate the visibility of a @@ -24227,54 +24367,49 @@ are affected. The commands that work with frame filters are: @code{-stack-list-locals} (@pxref{-stack-list-locals,, The -stack-list-locals command}). -A frame filter works by applying actions to an iterator that is passed -to that frame filter as a parameter. Typically, frame filters utilize -tools such as the Python's @code{itertools} module to modify the -iterator. If the frame filter modifies the iterator, it returns that -modified iterator, otherwise it returns the original iterator -unmodified. A frame filter must not alter the underlying @value{GDBN} -frame or frames, or attempt to alter the call-stack within -@value{GDBN}. Frame filters may only work on the iterator that is -provided. This preserves data integrity within @value{GDBN}. - -Frame filters are executed on a priority basis and care should be -taken that some frame filters may have been executed before, and that -some frame filters will be executed after. +A frame filter works by taking an iterator as an argument, applying +actions to the contents of that iterator, and returning another +iterator (or, possibly, the same iterator it was provided in the case +where the filter does not perform any operations). Typically, frame +filters utilize tools such as the Python's @code{itertools} module to +work with and create new iterators from the source iterator. +Regardless of how a filter chooses to apply actions, it must not alter +the underlying @value{GDBN} frame or frames, or attempt to alter the +call-stack within @value{GDBN}. This preserves data integrity within +@value{GDBN}. Frame filters are executed on a priority basis and care +should be taken that some frame filters may have been executed before, +and that some frame filters will be executed after. The Python dictionary @code{gdb.frame_filters} contains key/object -pairings that comprise a frame filter. These frame filters must -register with the dictionary directly. Frame filters in this +pairings that comprise a frame filter. FrameAsn filters in this dictionary are called @code{global} frame filters, and they are -available when debugging all inferiors. In addition to the +available when debugging all inferiors. These frame filters must +register with the dictionary directly. In addition to the @code{global} dictionary, there are other dictionaries that are loaded with different inferiors via auto-loading (@pxref{Python Auto-loading}). The two other areas where frame filter dictionaries can be found are: @code{gdb.Progspace} which contains a @code{frame_filters} dictionary attribute, and each @code{gdb.Objfile} -object which also contains a @code{frame_filters} dictionary attribute. +object which also contains a @code{frame_filters} dictionary +attribute. -Each frame filter object in these dictionaries is passed a single -Python iterator argument and should return a Python iterator. Each -frame filter object must conform to the frame filter interface -definition (@pxref{Frame Filters API}). The iterator returned by the -frame filter must contain only a collection of frame wrappers -(@pxref{Frame Wrapper API}), conforming to the frame wrapper interface -definition. +Each frame filter object in these dictionaries must conform to the +frame filter interface definition (@pxref{Frame Filter API}). When a command is executed from @value{GDBN} that is compatible with frame filters, @value{GDBN} combines the @code{global}, -@code{gdb.Progspace} and all @code{gdb.ObjFile} dictionaries currently +@code{gdb.Progspace} and all @code{gdb.Objfile} dictionaries currently loaded. All of the @code{gdb.Objfile} dictionaries are combined, as several frames, and thus several object files, might be in use. @value{GDBN} then prunes any frame filter whose @code{enabled} attribute is @code{False}. This pruned list is then sorted according to the @code{priority} attribute in each filter. Once the dictionaries are combined, pruned and sorted, @value{GDBN} then wraps -all frames in the call-stack with a @code{FrameWrapper} object, -and calls each filter in order. The input to the first frame filter -will be an initial iterator wrapping a collection of -@code{FrameWrapper} objects. The output from the previous filter -will always be the input to the next filter, and so on. +all frames in the call-stack with a @code{FrameDecorator} object, and +calls each filter in order. The input to the first frame filter will +be an initial iterator wrapping a collection of @code{FrameDecorator} +objects. The output from the previous filter will always be the input +to the next filter, and so on. Frame filters have a mandatory interface which each frame filter must implement, defined here: @@ -24304,19 +24439,19 @@ Note that the output (a Python iterator) from @code{Filter3} is passed to the input of @code{Filter2}, and so on. This @code{filter} method is passed a Python iterator. This iterator -contains a sequence of frame wrappers that wrap each @code{gdb.Frame}, -or another frame wrapper that wraps a frame wrapper. The first filter +contains a sequence of frame decorators that wrap each @code{gdb.Frame}, +or another frame decorator that wraps a frame decorator. The first filter that is executed in the sequence of frame filters will receive an -iterator entirely comprised of @code{BaseFrameWrapper} objects. +iterator entirely comprised of @code{FrameDecorator} objects. However, after each frame filter is executed, the previous frame -filter may have wrapped some or all of the frame wrappers with their -own frame wrapper. As Frame Wrappers must also conform to a mandatory -interface, these wrappers can be assumed to act in a uniform manner -(@pxref{Frame Wrapper API}). +filter may have wrapped some or all of the frame decorators with their +own frame decorator. As frame decorators must also conform to a mandatory +interface, these decorators can be assumed to act in a uniform manner +(@pxref{Frame Decorator API}). This method must return an object conforming to the Python iterator protocol. Each item in the iterator must be an object conforming to -the frame wrapper interface. If a frame filter does not wish to +the frame decorator interface. If a frame filter does not wish to perform any operations on this iterator, it should return that iterator untouched. @@ -24326,10 +24461,10 @@ raise and print an error. @defvar FrameFilter.name The @code{name} attribute must be Python string which contains the -name of the filter displayed by @value{GDBN} (@pxref{Managing Frame -Filters}). This attribute may contain any combination of letters, -numbers and spaces. Care should be taken to ensure that it is unique. -This attribute is mandatory. +name of the filter displayed by @value{GDBN} (@pxref{Frame Filter +Management}). This attribute may contain any combination of letters +or numbers. Care should be taken to ensure that it is unique. This +attribute is mandatory. @end defvar @defvar FrameFilter.enabled @@ -24355,47 +24490,51 @@ priority are executed in unsorted order in that priority slot. This attribute is mandatory. @end defvar -@node Frame Wrapper API -@subsubsection Wrapping and Decorating Frames. -@cindex frame wrapper api +@node Frame Decorator API +@subsubsection Decorating Frames. +@cindex frame decorator api -Frame wrappers are sister objects to frame filters (@pxref{Frame -Filters API}). Frame wrappers are applied by a frame filter and can +Frame decorators are sister objects to frame filters (@pxref{Frame +Filter API}). Frame decorators are applied by a frame filter and can only be used in conjunction with frame filters. -The purpose of a frame wrapper is to customize the printed content of -each frame. Frame wrappers have a mandatory interface, defined below. -A frame wrapper object works on a single frame, but a frame wrapper -object can be applied to multiple frames. +The purpose of a frame decorator is to customize the printed content +of each @code{gdb.Frame} in commands where frame filters are executed. +This concept is called decorating a frame. Frame decorators decorate +a @code{gdb.Frame} with customized data operation contained with each +API call. This separates the actual data contained in a +@code{gdb.Frame} from the decorated data produced by a frame +decorator. This abstraction is necessary to maintain integrity of the +data contained in each @code{gdb.Frame}. + +Frame decorators have a mandatory interface, defined below. -@value{GDBN} already contains a frame wrapper called -@code{BaseFrameWrapper}. This contains substantial amounts of -boilerplate code to print the content of frames. It is recommended -that other frame wrappers inherit and extend this object, and only to -override the methods needed. The Python code for -@code{BaseFrameWrapper} can be found in -@file{@var{data-directory}/python/gdb} +@value{GDBN} already contains a frame decorator called +@code{FrameDecorator}. This contains substantial amounts of +boilerplate code to decorate the content of a @code{gdb.Frame}. It is +recommended that other frame decorators inherit and extend this +object, and only to override the methods needed. -@defun FrameWrapper.elided () +@defun FrameDecorator.elided () The @code{elided} method groups frames together in a hierarchical system. An example would be an interpreter call that occurs over many frames but might be better represented as a group of frames distinct from the other frames. -The @code{elided} function must return an iterator that conforms to the -Python iterator protocol. This iterator must contain the frames that -are being elided wrapped in a suitable frame wrapper. If there are no -frames being elided in this frame wrapper, this method must return a -Python @code{None}. Elided frames are indented from normal frames in -a @code{CLI} backtrace, or in the case of @code{GDB/MI}, are placed in -the @code{children} field of the eliding frame. +The @code{elided} function must return an iterable and this iterable +must contain the frames that are being elided wrapped in a suitable +frame decorator. If there are no frames being elided in this frame +decorator, this method must return @code{None}. Elided +frames are indented from normal frames in a @code{CLI} backtrace, or +in the case of @code{GDB/MI}, are placed in the @code{children} field +of the eliding frame. It is the frame filter's task to also filter out the elided frames from the source iterator. This will avoid printing the frame twice. @end defun -@defun FrameWrapper.function () +@defun FrameDecorator.function () This method returns the name of the function in the frame that is to be printed. @@ -24403,34 +24542,34 @@ be printed. This method must return a Python string describing the function, or a Python @code{None}. -If this function returns a Python @code{None}, @value{GDBN} will not -print any data for this field. +If this function returns @code{None}, @value{GDBN} will not print any +data for this field. @end defun -@defun FrameWrapper.address () +@defun FrameDecorator.address () This method returns the address of the frame that is to be printed. This method must return a Python numeric integer type of sufficient -size to describe the address of the frame, or a Python @code{None}. +size to describe the address of the frame, @code{None}. -If this function returns a Python @code{None}, @value{GDBN} will not -print any data for this field. +If this function returns @code{None}, @value{GDBN} will not print any +data for this field. @end defun -@defun FrameWrapper.filename () +@defun FrameDecorator.filename () This method returns the filename and path associated with this frame. -This method must return a Python string containing the filename and the -path to the object file backing the frame, or a Python @code{None}. +This method must return a Python string containing the filename and +the path to the object file backing the frame, or @code{None}. -If this function returns a Python @code{None}, @value{GDBN} will not -print any data for this field. +If this function returns @code{None}, @value{GDBN} will not print any +data for this field. @end defun -@defun FrameWrapper.line (): +@defun FrameDecorator.line (): This method returns the line number associated with the current position within the function addressed by this frame. @@ -24438,14 +24577,14 @@ position within the function addressed by this frame. This method must return a Python integer type, or a Python @code{None}. -If this function returns a Python @code{None}, @value{GDBN} will not -print any data for this field. +If this function returns @code{None}, @value{GDBN} will not print any +data for this field. @end defun -@defun FrameWrapper.frame_args () +@defun FrameDecorator.frame_args () @anchor{frame_args} -This method must return an iterator that conforms to the Python -iterator protocol, or a Python @code{None}. This iterator must + +This method must return an iterable @code{None}. This iterable must contain objects that implement two methods, described here. The object must implement an @code{argument} method which takes no @@ -24453,10 +24592,9 @@ parameters and must return a @code{gdb.Symbol} (@pxref{Symbols In Python}), or a Python string. It must also implement a @code{value} method which takes no parameters and which must return a @code{gdb.Value} (@pxref{Values From Inferior}), a Python value, or -@code{None}. If the @code{value} method returns a Python @code{None}, -and the @code{argument} method returns a @code{gdb.Symbol}, -@value{GDBN} will look-up and print the value of the @code{gdb.Symbol} -automatically. +@code{None}. If the @code{value} method returns @code{None}, and the +@code{argument} method returns a @code{gdb.Symbol}, @value{GDBN} will +look-up and print the value of the @code{gdb.Symbol} automatically. A brief example: @@ -24474,7 +24612,7 @@ class SymValueWrapper (): return self.sym -class SomeFrameWrapper() +class SomeFrameDecorator() ... ... def frame_args(self): @@ -24496,23 +24634,22 @@ class SomeFrameWrapper() @end smallexample Even if the @code{frame_args} method returns only a single object, it hooks/post-receive -- Repository for Project Archer.