From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 89179 invoked by alias); 1 Dec 2016 01:04:36 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 89167 invoked by uid 89); 1 Dec 2016 01:04:35 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-4.8 required=5.0 tests=BAYES_00,RCVD_IN_DNSWL_NONE,RP_MATCHES_RCVD,SPF_PASS autolearn=ham version=3.3.2 spammy=Listening, listening, D*r X-HELO: mail-pg0-f74.google.com Received: from mail-pg0-f74.google.com (HELO mail-pg0-f74.google.com) (74.125.83.74) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Thu, 01 Dec 2016 01:04:25 +0000 Received: by mail-pg0-f74.google.com with SMTP id g186so18646189pgc.3 for ; Wed, 30 Nov 2016 17:04:25 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:message-id:date:subject:from:to:cc; bh=ZjAqyrTvixjle4eM31LZNZyBQzN5MDk8OWeHX98mzLA=; b=iSvOKlDy357gmoNwLzEtiFoCpiMtZRvUiyOpkOaCsrHMK+zSqFwP//TVUG0v8BQk6C fQy8m07AP0DoXi4BAjCc985qo6jxBtIHg6ORJTG88pG3J9+xEC3V1uSzu/MnvSomEZPG HeIhfDVXngmuGb94bpVT5fTvyS9Y9DCRb2seuOFZdYm9aSJpsHl520PEqOugdZsZ7OPm 0OCr7vmDK+OalE5CyclJjPnIJxOiZZmwol8rClN+Whx2O6veSGKtMXd37d8wUr0UzNfW ZbbLUoMK3+ZdU3Rg2e0UI7kfVj1M34uspQu3DAAF4+w49MlqiM9Grkm1AyUG2FzUwm+3 pPXg== X-Gm-Message-State: AKaTC02xG9kROzKLYhASL35gilYY2YGB9Dto8SrmyxREUcQWTUzrK3w3bzNfjjXXFHd6pUV7NA== MIME-Version: 1.0 X-Received: by 10.98.73.23 with SMTP id w23mr6178233pfa.28.1480554264132; Wed, 30 Nov 2016 17:04:24 -0800 (PST) Message-ID: <94eb2c0b85f8fc52fd05428e6607@google.com> Date: Thu, 01 Dec 2016 01:04:00 -0000 Subject: Re: [PATCH v3 8/8] Add documentation for new instruction record Python bindings. From: Doug Evans To: Tim Wiederhake Cc: gdb-patches@sourceware.org, palves@redhat.com, markus.t.metzger@intel.com Content-Type: text/plain; charset=UTF-8; format=flowed; delsp=yes X-IsSubscribed: yes X-SW-Source: 2016-12/txt/msg00003.txt.bz2 Tim Wiederhake writes: > 2016-11-21 Tim Wiederhake > > 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.]