This is the mail archive of the gdb@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Proposed tracepoint enhancements, GDB manual patch


Stan Shebs wrote:
As I mentioned a couple months ago, CodeSourcery is interested in extending tracepoints, most notably to make them be more like breakpoints with conditionals and such. We're also planning to add "trace state variables", which are kind of like convenience variables managed by the target's agent, and a file format for raw trace data stored offline.

Woo hoo! ;-)



Things are still in the planning stage (I've been madly
hacking to get a basic stub running), so everything is still tweakable, and feel free to comment on lamenesses or omissions. This first bit takes the form of a patch to GDB's tracepoint chapter, so it should be read with an eye to how user will learn how to use tracepoints.

Stan



------------------------------------------------------------------------

Index: gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.535
diff -p -r1.535 gdb.texinfo
*** gdb.texinfo 18 Nov 2008 21:31:27 -0000 1.535
--- gdb.texinfo 20 Nov 2008 07:28:40 -0000
*************** This chapter describes the tracepoint co
*** 8500,8509 ****
@section Commands to Set Tracepoints
Before running such a @dfn{trace experiment}, an arbitrary number of
! tracepoints can be set. Like a breakpoint (@pxref{Set Breaks}), a
! tracepoint has a number assigned to it by @value{GDBN}. Like with
! breakpoints, tracepoint numbers are successive integers starting from
! one. Many of the commands associated with tracepoints take the
tracepoint number as their argument, to identify which tracepoint to
work on.
--- 8500,8509 ----
@section Commands to Set Tracepoints
Before running such a @dfn{trace experiment}, an arbitrary number of
! tracepoints can be set. A tracepoint is actually a special type of
! breakpoint (@pxref{Set Breaks}), so you can manipulate it using
! standard breakpoint commands. For instance, each tracepoint has an
! integer assigned to it by @value{GDBN}, and many commands take the
tracepoint number as their argument, to identify which tracepoint to
work on.
*************** conditions and actions.
*** 8521,8526 ****
--- 8521,8528 ----
* Create and Delete Tracepoints::
* Enable and Disable Tracepoints::
* Tracepoint Passcounts::
+ * Tracepoint Conditions::
+ * Trace State Variables::
* Tracepoint Actions::
* Listing Tracepoints::
* Starting and Stopping Trace Experiments::
*************** conditions and actions.
*** 8532,8547 ****
@table @code
@cindex set tracepoint
@kindex trace
! @item trace
The @code{trace} command is very similar to the @code{break} command.
! Its argument can be a source line, a function name, or an address in
! the target program. @xref{Set Breaks}. The @code{trace} command
! defines a tracepoint, which is a point in the target program where the
! debugger will briefly stop, collect some data, and then allow the
! program to continue. Setting a tracepoint or changing its commands
! doesn't take effect until the next @code{tstart} command; thus, you
! cannot change the tracepoint attributes once a trace experiment is
! running.
Here are some examples of using the @code{trace} command:
--- 8534,8549 ----
@table @code
@cindex set tracepoint
@kindex trace
! @item trace @var{location}
The @code{trace} command is very similar to the @code{break} command.
! Its argument @var{location} can be a source line, a function name, or
! an address in the target program. @xref{Set Breaks}. The
! @code{trace} command defines a tracepoint, which is a point in the
! target program where the debugger will briefly stop, collect some
! data, and then allow the program to continue. Setting a tracepoint or
! changing its commands doesn't take effect until the next @code{tstart}
! command; thus, you cannot change the tracepoint attributes once a
! trace experiment is running.
Here are some examples of using the @code{trace} command:
*************** Here are some examples of using the @cod
*** 8560,8565 ****
--- 8562,8588 ----
@noindent
You can abbreviate @code{trace} as @code{tr}.
+ @item trace @var{location} if @var{cond}
+ Set a tracepoint with condition @var{cond}; evaluate the expression
+ @var{cond} each time the tracepoint is reached, and collect data only
+ if the value is nonzero---that is, if @var{cond} evaluates as true.
+ @xref{Tracepoint Conditions, ,Tracepoint Conditions}, for more
+ information on tracepoint conditions.
+ + @cindex set fast tracepoint
+ @kindex ftrace
+ @item ftrace @var{location} [ if @var{cond} ]
+ The @code{ftrace} command sets a ``fast'' tracepoint. For targets that
+ support it, fast tracepoints will use a more efficient but possibly
+ less general technique to trigger data collection, such as a jump
+ instruction instead of a trap, or hardware support. It may not be
+ possible to create a fast tracepoint at the desired location, in which
+ case the command will exit with an explanatory message. (The regular
+ @code{trace} command may also create fast tracepoints if possible.)
+ + @value{GDBN} handles arguments to @code{ftrace} exactly as for
+ @code{trace}.
+ @vindex $tpnum
@cindex last tracepoint number
@cindex recent tracepoint number
*************** of the most recently set tracepoint.
*** 8569,8606 ****
@kindex delete tracepoint
@cindex tracepoint deletion
! @item delete tracepoint @r{[}@var{num}@r{]}
! Permanently delete one or more tracepoints. With no argument, the
! default is to delete all tracepoints.
Examples:
@smallexample
! (@value{GDBP}) @b{delete trace 1 2 3} // remove three tracepoints
! (@value{GDBP}) @b{delete trace} // remove all tracepoints
@end smallexample
@noindent
! You can abbreviate this command as @code{del tr}.
@end table
@node Enable and Disable Tracepoints
@subsection Enable and Disable Tracepoints
@table @code
! @kindex disable tracepoint
! @item disable tracepoint @r{[}@var{num}@r{]}
! Disable tracepoint @var{num}, or all tracepoints if no argument
! @var{num} is given. A disabled tracepoint will have no effect during
! the next trace experiment, but it is not forgotten. You can re-enable
! a disabled tracepoint using the @code{enable tracepoint} command.
! ! @kindex enable tracepoint
! @item enable tracepoint @r{[}@var{num}@r{]}
! Enable tracepoint @var{num}, or all tracepoints. The enabled
! tracepoints will become effective the next time a trace experiment is
! run.
@end table
@node Tracepoint Passcounts
--- 8592,8628 ----
@kindex delete tracepoint
@cindex tracepoint deletion
! @item delete @r{[}@var{num}@r{]}
! Permanently delete one or more tracepoints.
Examples:
@smallexample
! (@value{GDBP}) @b{delete 1 2 3} // remove three tracepoints
! (@value{GDBP}) @b{delete} // remove all breakpoints/tracepoints
@end smallexample
@noindent
! You can abbreviate this command as @code{del}.
@end table
@node Enable and Disable Tracepoints
@subsection Enable and Disable Tracepoints
@table @code
! @kindex disable
! @item disable @r{[}@var{num}@r{]}
! Disable tracepoint @var{num}, or all tracepoints and breakpoints if no
! argument @var{num} is given. A disabled tracepoint will have no
! effect during the next trace experiment, but it is not forgotten. You
! can re-enable a disabled tracepoint using the @code{enable} command.
! ! @kindex enable
! @item enable @r{[}@var{num}@r{]}
! Enable tracepoint @var{num}, or all tracepoints and breakpoints. The
! enabled tracepoints will become effective the next time a trace
! experiment is run.
@end table
@node Tracepoint Passcounts
*************** Examples:
*** 8639,8644 ****
--- 8661,8752 ----
@end smallexample
@end table
+ @node Tracepoint Conditions
+ @subsection Tracepoint Conditions
+ @cindex conditional breakpoints
+ @cindex breakpoint conditions
+ + The simplest sort of tracepoint collects data every time your program
+ reaches a specified place. You can also specify a @dfn{condition} for
+ a tracepoint. A condition is just a Boolean expression in your
+ programming language (@pxref{Expressions, ,Expressions}). A
+ tracepoint with a condition evaluates the expression each time your
+ program reaches it, and data collection happens only if the condition
+ is @emph{true}. Tracepoint conditions can have side effects.
+ + Tracepoint conditions can be specified when a tracepoint is set, by
+ using @samp{if} in the arguments to the @code{trace} command.
+ @xref{Set Trace, ,Setting Tracepoints}. They can also be set or
+ changed at any time with the @code{condition} command.
+ + @table @code
+ @kindex condition
+ @item condition @var{tpnum} @var{expression}
+ Specify @var{expression} as the tracepoint condition for tracepoint
+ @var{tpnum}. After you set a condition, tracepoint @var{tpnum} runs
+ its actions only if the value of @var{expression} is true (nonzero,
+ in C). When you use @code{condition}, @value{GDBN} checks
+ @var{expression} immediately for syntactic correctness, and to
+ determine whether symbols in it have referents in the context of your
+ breakpoint. If @var{expression} uses symbols not referenced in the
+ context of the breakpoint, @value{GDBN} prints an error message:
+ + @smallexample
+ No symbol "foo" in current context.
+ @end smallexample
+ + @noindent
+ @value{GDBN} does not actually evaluate @var{expression} at the time
+ the @code{condition} command (or a command that sets a tracepoint with
+ a condition, like @code{trace if @dots{}}) is given, however.
+ @xref{Expressions, ,Expressions}. Instead, @value{GDBN} encodes the
+ expression into a form suitable for execution on the target,
+ independently of @value{GDBN}. Global variables become raw memory
+ locations, locals become stack accesses, and so forth.
+ + @item condition @var{tpnum}
+ Remove the condition from tracepoint number @var{tpnum}. It becomes
+ an ordinary unconditional tracepoint.
+ @end table
+ + @node Trace State Variables
+ @subsection Trace State Variables
+ + A @dfn{race state variable} is a special type of variable that is
+ created and managed by target-side code. The syntax is the same as
+ that for GDB's convenience variables (a string prefixed with ``$''),
+ but they are stored on the target. They are created implicitly by
+ being assigned to in conditional and action expressions, or
+ explicitly, with a @code{tvariable} command. They are always signed
+ integers, and always updated atomically.
+ + Trace state variables are remembered by @value{GDBN}, and downloaded
+ to the target along with tracepoint information when the trace
+ experiment starts. There are no intrinsic limits on the number of
+ trace state variables, beyond memory limitations of the target.
+ + @table @code
+ + @item tvariable $@var{name} [ = @var{expression} ]
+ The @code{tvariable} command creates a new trace state variable named
+ @var{name}, and optionally sets it to the value of @var{expression}.
+ @var{expression} is evaluated when this command is entered; a
+ non-integer value will result in an error. A second @code{tvariable}
+ command with the same name assigns a new value to the variable.
+ + @item tvariable delete $@var{name}
+ This command deletes the trace state variable named @var{name}.
+ + @item info tvariables
+ List all the trace state variables along with their values.
+ + @item $trace_timestamp
+ This trace state variable is always defined, and its value is the
+ current time at the moment it is accessed, expressed in
+ system-specific units.
+ + @end table
+ @node Tracepoint Actions
@subsection Tracepoint Action Lists
*************** recently defined (so that you can define
*** 8653,8659 ****
@code{actions} without bothering about its number). You specify the
actions themselves on the following lines, one action at a time, and
terminate the actions list with a line containing just @code{end}. So
! far, the only defined actions are @code{collect} and
@code{while-stepping}.
@cindex remove actions from a tracepoint
--- 8761,8767 ----
@code{actions} without bothering about its number). You specify the
actions themselves on the following lines, one action at a time, and
terminate the actions list with a line containing just @code{end}. So
! far, the only defined actions are @code{collect}, @code{do}, and
@code{while-stepping}.
@cindex remove actions from a tracepoint
*************** and follow it immediately with @samp{end
*** 8663,8668 ****
--- 8771,8778 ----
@smallexample
(@value{GDBP}) @b{collect @var{data}} // collect some data
+ (@value{GDBP}) @b{do @var{exp}} // evaluate an expression
+ (@value{GDBP}) @b{while-stepping 5} // single-step 5 times, collect data
(@value{GDBP}) @b{end} // signals the end of actions.
*************** Enter actions for tracepoint 1, one per *** 8685,8690 ****
--- 8795,8801 ----
> collect $regs
> while-stepping 12
> collect $fp, $sp
+ > do $stepcount = $stepcount + 1
> end
end
@end smallexample
*************** arguments separated by commas: the effec
*** 8714,8724 ****
The command @code{info scope} (@pxref{Symbols, info scope}) is
particularly useful for figuring out what data to collect.
@kindex while-stepping @r{(tracepoints)}
@item while-stepping @var{n}
Perform @var{n} single-step traces after the tracepoint, collecting
new data at each step. The @code{while-stepping} command is
! followed by the list of what to collect while stepping (followed by
its own @code{end} command):
@smallexample
--- 8825,8840 ----
The command @code{info scope} (@pxref{Symbols, info scope}) is
particularly useful for figuring out what data to collect.
+ @item do @var{expr1}, @var{expr2}, @dots{}
+ Evaluate @var{expr1}, @var{expr2}, etc, and discard the results. This
+ is useful for setting the value of a trace state variable without
+ filling up the trace buffer.
+ @kindex while-stepping @r{(tracepoints)}
@item while-stepping @var{n}
Perform @var{n} single-step traces after the tracepoint, collecting
new data at each step. The @code{while-stepping} command is
! followed by the list of what to do or collect while stepping (followed by
its own @code{end} command):
@smallexample
*************** its own @code{end} command):
*** 8731,8736 ****
--- 8847,8858 ----
@noindent
You may abbreviate @code{while-stepping} as @code{ws} or
@code{stepping}.
+ + @item set default-collect @var{expr1}, @var{expr2}, @dots{}
+ This variable is a list of expressions to collect at each tracepoint
+ hit, effectively an additional @code{collect} prepended to every
+ tracepoint action list.
+ @end table
@node Listing Tracepoints
*************** begins collecting data. This has the si
*** 8789,8794 ****
--- 8911,8923 ----
the data collected in the trace buffer during the previous trace
experiment.
+ The trace experiment runs independently of any other @value{GDBN}
+ interaction with your program. You may stop the program at a
+ breakpoint, single-step, change program values, and so forth. Of
+ course, confusion may ensue if you are manually altering program data
+ while it is being collected, which could happen if the trace is
+ running while you are in non-stop debugging mode.
+ @kindex tstop
@cindex stop a running trace experiment
@item tstop
*************** for examining the trace data. The basic
*** 8832,8851 ****
collects a trace @dfn{snapshot} every time it is hit and another
snapshot every time it single-steps. All these snapshots are
consecutively numbered from zero and go into a buffer, and you can
! examine them later. The way you examine them is to @dfn{focus} on a
! specific trace snapshot. When the remote stub is focused on a trace
! snapshot, it will respond to all @value{GDBN} requests for memory and
! registers by reading from the buffer which belongs to that snapshot,
! rather than from @emph{real} memory or registers of the program being
! debugged. This means that @strong{all} @value{GDBN} commands
! (@code{print}, @code{info registers}, @code{backtrace}, etc.) will
! behave as if we were currently debugging the program state as it was
! when the tracepoint occurred. Any requests for data that are not in
! the buffer will fail.
@menu
* tfind:: How to select a trace snapshot
* tdump:: How to display all data for a snapshot
* save-tracepoints:: How to save tracepoints for a future run
@end menu
--- 8961,8981 ----
collects a trace @dfn{snapshot} every time it is hit and another
snapshot every time it single-steps. All these snapshots are
consecutively numbered from zero and go into a buffer, and you can
! examine them later. The way you examine them is to @dfn{find} a
! specific trace snapshot. When the target has found a trace snapshot,
! it will respond to all @value{GDBN} requests for memory and registers
! by reading from the buffer which belongs to that snapshot, rather than
! from @emph{real} memory or registers of the program being debugged.
! This means that @strong{all} @value{GDBN} commands (@code{print},
! @code{info registers}, @code{backtrace}, etc.) will behave as if we
! were currently debugging the program state as it was when the
! tracepoint occurred. Any requests for data that are not in the buffer
! will fail.
@menu
* tfind:: How to select a trace snapshot
* tdump:: How to display all data for a snapshot
+ * Using a Trace File:: How to get trace snapshots from a file
* save-tracepoints:: How to save tracepoints for a future run
@end menu
*************** gdb_long_test = 17 '\021'
*** 9025,9030 ****
--- 9155,9203 ----
(@value{GDBP})
@end smallexample
+ @node Using a Trace File
+ @subsection Using a Trace File
+ + It may be that the trace experiment has finished running after GDB has
+ disconnected from the target, and the results have been saved to a
+ file. You can give a special @code{target} command to use this file as
+ the source of trace snapshots.
+ + @table @code
+ + @item target tfile @var{filename}
+ This target command causes @value{GDBN} to use the contents of
+ @var{filename} as a source of trace snapshots that can be found with
+ @var{tfind} and used as described above. Subsequent target commands,
+ such as @code{target remote}, will terminate this mode and resume
+ normal debugging. If the tracepoints recorded in the file are
+ different from the ones currently defined by @value{GDBN}, the
+ debugger will warn of the discrepancy and create new tracepoints from
+ the file's data.
+ + @end table
+ + A file of trace data begins with the byte 0x7f (to indicate that it
+ includes some binary data), followed by the chararacters
+ 'TRACE\n'. Each tracepoint is then listed, with its properties
+ recorded in ASCII, followed by runs of trace frames, which are
+ recorded as raw binary.
+ + Each tracepoint record has the form
+ + <num>:<addr>:<enb>:<stepcnt>:<passcnt>:<cond>:<actions>\n
+ + where <cond> and <actions> are hex dumps of the agent expression
+ bytecodes.
+ + Groups of trace frames are introduced with a 32-bit word, of which
+ the first half is a tracepoint <num>, and the second half of which
+ is a count of frames following. Each trace frame consists of the raw
+ data as collected; its contents may be parsed by interpreting the
+ action expression for the frame's tracepoint.
+ + The end of the file is signified with a 32-bit word of all zeros.
+ @node save-tracepoints
@subsection @code{save-tracepoints @var{filename}}
@kindex save-tracepoints
*************** Files}).
*** 9041,9046 ****
--- 9214,9223 ----
@cindex tracepoint variables
@cindex convenience variables for tracepoints
+ Several @value{GDBN} convenience variables are available to simplify
+ the writing of analysis scripts. Note that these are not the same as
+ trace state variables, which are managed by the target.
+ @table @code
@vindex $trace_frame
@item (int) $trace_frame


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]