[PATCH v3 8/8] Add documentation for new instruction record Python bindings.

Doug Evans dje@google.com
Thu Dec 1 01:04:00 GMT 2016


Tim Wiederhake writes:
  > 2016-11-21  Tim Wiederhake  <tim.wiederhake@intel.com>
  >
  > gdb/ChangeLog:
  >
  > 	* NEWS: Add record Python bindings entry.
  >
  > gdb/doc/ChangeLog:
  >
  > 	* python.texi (Recordings In Python): New section.
  >
  >
  > ---
  >  gdb/NEWS            |   4 +
  >  gdb/doc/python.texi | 237  
++++++++++++++++++++++++++++++++++++++++++++++++++++
  >  2 files changed, 241 insertions(+)
  >
  > diff --git a/gdb/NEWS b/gdb/NEWS
  > index a597405..b39860e 100644
  > --- a/gdb/NEWS
  > +++ b/gdb/NEWS
  > @@ -3,6 +3,10 @@
  >
  >  *** Changes since GDB 7.12
  >
  > +* Python Scripting
  > +
  > +  ** New functions to start, stop and access a running btrace recording.
  > +
  >  * Building GDB and GDBserver now requires a C++11 compiler.
  >
  >    For example, GCC 4.8 or later.
  > diff --git a/gdb/doc/python.texi b/gdb/doc/python.texi
  > index d6507e5..70b8d37 100644
  > --- a/gdb/doc/python.texi
  > +++ b/gdb/doc/python.texi
  > @@ -151,6 +151,7 @@ optional arguments while skipping others.  Example:
  >  * 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.
  > +* Recordings In Python::        Accessing recordings from Python.
  >  * Commands In Python::          Implementing new commands in Python.
  >  * Parameters In Python::        Adding new @value{GDBN} parameters.
  >  * Functions In Python::         Writing new convenience functions.
  > @@ -3062,6 +3063,242 @@ Return a Boolean indicating whether the thread  
is running.
  >  Return a Boolean indicating whether the thread is exited.
  >  @end defun
  >
  > +@node Recordings In Python
  > +@subsubsection Recordings In Python
  > +@cindex recordings in python
  > +
  > +The following recordings-related functions
  > +(@pxref{Process Record and Replay}) are available in the @code{gdb}
  > +module:
  > +
  > +@defun gdb.start_recording (@r{[}method@r{]}, @r{[}format@r{]})
  > +Start a recording using the given @var{method} and @var{format}.  If
  > +no @var{format} is given, the default format for the recording method
  > +is used.  If no @var{method} is given, the default method will be used.
  > +Returns a @code{gdb.Record} object on success.  Throw an exception on
  > +failure.
  > +
  > +The following strings can be passed as @var{method}:
  > +
  > +@itemize @bullet
  > +@item
  > +@code{"full"}
  > +@item
  > +@code{"btrace"}: Possible values for @var{format}: @code{"pt"},
  > +@code{"bts"} or leave out for default format.
  > +@end itemize
  > +@end defun
  > +
  > +@defun gdb.current_recording ()
  > +Access a currently running recording.  Return a @code{gdb.Record}
  > +object on success.  Return @code{None} if no recording is currently
  > +active.
  > +@end defun
  > +
  > +@defun gdb.stop_recording ()
  > +Stop the current recording.  Throw an exception if no recording is
  > +currently active.  All record objects become invalid after this call.
  > +@end defun
  > +
  > +A @code{gdb.Record} object has the following attributes:
  > +
  > +@defvar Record.method
  > +A string with the current recording method, e.g.@: @code{full} or
  > +@code{btrace}.
  > +@end defvar
  > +
  > +@defvar Record.format
  > +A string with the current recording format, e.g.@: @code{bt} or
  > +@code{pts}.  Can be empty.
  > +@end defvar
  > +
  > +@defvar Record.begin
  > +A format specific instruction object representing the first instruction
  > +in this recording.
  > +@end defvar
  > +
  > +@defvar Record.end
  > +A format specific instruction object representing the current
  > +instruction, that is not actually part of the recording.
  > +@end defvar
  > +
  > +@defvar Record.replay_position
  > +The instruction representing the current replay position.  If there is
  > +no replay active, this will be @code{None}.
  > +@end defvar
  > +
  > +@defvar Record.instruction_history
  > +A list with all recorded instructions.
  > +@end defvar
  > +
  > +@defvar Record.function_call_history
  > +A list with all recorded function call segments.
  > +@end defvar
  > +
  > +A @code{gdb.Record} object has the following methods:
  > +
  > +@defun Record.goto (instruction)
  > +Move the replay position to the given @var{instruction}.
  > +@end defun
  > +
  > +The attributes and methods of instruction objects depend on the current
  > +recording format.  Currently, only btrace instructions are supported.
  > +
  > +A @code{gdb.BtraceInstruction} object has the following attributes:
  > +
  > +@defvar BtraceInstruction.number
  > +An integer identifying this instruction.  @var{number} corresponds to
  > +the numbers seen in @code{record instruction-history}
  > +(@pxref{Process Record and Replay}).
  > +@end defvar
  > +
  > +@defvar BtraceInstruction.error
  > +An integer identifying the error code for gaps in the record.
  > +@code{None} for regular instructions.
  > +@end defvar
  > +
  > +@defvar BtraceInstruction.symbol
  > +A @code{gdb.Symtab_and_line} object representing the associated line
  > +and symbol of this instruction.  May be @code{None} if the instruction
  > +is a gap.
  > +@end defvar
  > +
  > +@defvar BtraceInstruction.pc
  > +An integer representing this instruction's address.  May be @code{None}
  > +if the instruction is a gap or the debug symbols could not be read.
  > +@end defvar
  > +
  > +@defvar BtraceInstruction.data
  > +A buffer with the raw instruction data.  May be @code{None} if the
  > +instruction is a gap.
  > +@end defvar
  > +
  > +@defvar BtraceInstruction.decoded
  > +A human readable string with the decoded instruction.  Contains the
  > +error message for gaps.
  > +@end defvar

Ah.
Supporting printing of the error message for gaps may be a good reason
to have BtraceInstruction.decoded (see review of 6(?)/8).

Ok, I guess I don't mind the existence of BtraceInstruction.decoded.

  > +
  > +@defvar BtraceInstruction.size
  > +The size of the instruction in bytes.  Will be @code{None} if the
  > +instruction is a gap.
  > +@end defvar
  > +
  > +@defvar BtraceInstruction.is_speculative
  > +A boolean indicating whether the instruction was executed
  > +speculatively.  Will be @code{None} for gaps.
  > +@end defvar
  > +
  > +The attributes and methods of function call objects depend on the
  > +current recording format.  Currently, only btrace function calls are
  > +supported.
  > +
  > +A @code{gdb.BtraceFunctionCall} object has the following attributes:
  > +
  > +@defvar BtraceFunctionCall.number
  > +An integer identifying this function call.  @var{number} corresponds to
  > +the numbers seen in @code{record function-call-history}
  > +(@pxref{Process Record and Replay}).
  > +@end defvar
  > +
  > +@defvar BtraceFunctionCall.symbol
  > +A @code{gdb.Symbol} object representing the associated symbol.  May be
  > +@code{Node} if the function call is a gap or the debug symbols could
  > +not be read.
  > +@end defvar
  > +
  > +@defvar BtraceFunctionCall.level
  > +An integer representing the function call's stack level.  May be
  > +@code{None} if the function call is a gap.
  > +@end defvar
  > +
  > +@defvar BtraceFunctionCall.instructions
  > +A list of instructions associated with this function call.
  > +@end defvar
  > +
  > +@defvar BtraceFunctionCall.up
  > +A @code{gdb.BtraceFunctionCall} object representing the caller's
  > +function segment.  If the call has not been recorded, this will be the
  > +function segment to which control returns.  If neither the call nor the
  > +return have been recorded, this will be @code{None}.
  > +@end defvar
  > +
  > +@defvar BtraceFunctionCall.prev_sibling
  > +A @code{gdb.BtraceFunctionCall} object representing the previous
  > +segment of this function call.  May be @code{None}.
  > +@end defvar
  > +
  > +@defvar BtraceFunctionCall.next_sibling
  > +A @code{gdb.BtraceFunctionCall} object representing the next segment of
  > +this function call.  May be @code{None}.
  > +@end defvar
  > +
  > +The following example demonstrates the usage of these objects and
  > +functions to create a function that will rewind a record to the last
  > +time a function in a different file was executed.  This would typically
  > +be used to track the execution of user provided callback functions in a
  > +library which typically are not visible in a back trace.
  > +
  > +@smallexample
  > +def bringback ():
  > +    rec = gdb.current_recording ()
  > +    if not rec:
  > +        return
  > +
  > +    insn = rec.instruction_history
  > +    if len (insn) == 0:
  > +        return
  > +
  > +    try:
  > +        position = insn.index (rec.replay_position)
  > +    except:
  > +        position = -1
  > +    try:
  > +        filename = insn[position].symbol.symtab.fullname ()
  > +    except:
  > +        filename = None
  > +
  > +    for i in reversed (insn[:position]):
  > +	try:
  > +            current = i.symbol.symtab.fullname ()
  > +	except:
  > +            current = None
  > +
  > +        if filename == current:
  > +            continue
  > +
  > +        rec.goto (i)
  > +        return
  > +@end smallexample
  > +
  > +Another possible application is to write a function that counts the
  > +number of code executions in a given line range.  This line range can
  > +contain parts of functions or span across several functions and is not
  > +limited to be contiguous.
  > +
  > +@smallexample
  > +def countrange (filename, linerange):
  > +    count = 0
  > +
  > +    def filter_only (file_name):
  > +        for call in gdb.current_recording ().function_call_history:
  > +            try:
  > +                if file_name in call.symbol.symtab.fullname ():
  > +                    yield call
  > +            except:
  > +                pass
  > +
  > +    for c in filter_only (filename):
  > +        for i in c.instructions:
  > +            try:
  > +                if i.symbol.line in linerange:
  > +                    count += 1
  > +                    break;
  > +            except:
  > +                    pass
  > +
  > +    return count
  > +@end smallexample
  > +
  >  @node Commands In Python
  >  @subsubsection Commands In Python
  >
  > --
  > 2.7.4
  >

Love the examples.

I suspect a FAQ will be "Why isn't this working?"
and the answer will be "The appropriate libipt (or whatever)
support is missing."

Can you add a loud (bold) comment somewhere at the start
of this node that reminds the reader that the necessary
support needs to be configured into gdb, and an @xref
to the section that describes how to get such support.
[I'm assuming/hoping the @xref target already exists.]



More information about the Gdb-patches mailing list