Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1238180
  • 博文数量: 264
  • 博客积分: 10772
  • 博客等级: 上将
  • 技术积分: 2325
  • 用 户 组: 普通用户
  • 注册时间: 2007-07-25 11:54
文章分类

全部博文(264)

文章存档

2012年(4)

2011年(51)

2010年(31)

2009年(57)

2008年(51)

2007年(70)

分类: C/C++

2008-12-29 14:02:13

不知道有没有用,先记下来再说

Tracing program execution: the record/playback model

Some program behaviors can be analyzed only by collecting data over long periods of time for later analysis. Other problems occur in sections of code that are too time-sensative to be debugged interactively. In these cases, tracing may be more appropriate than breakpoint debugging.

This section discusses the following topics.

Like a breakpoint, a tracepoint makes your program stop whenever a certain point in the program is reached. However, while a breakpoint stops the program for a "long" time (while GDB prompts you and lets you type commands), a tracepoint stops the program for only a "short" time, after which the program gets to continue with minimal disruption of its behavior. During this "short" interval, the trace mechanism records the fact that it has been there (ie. that the tracepoint was executed), and may also perform certain actions that you've requested such as recording the values of selected variables and registers. Thus it's not well defined how long a "short" time is, but in any event it will be thousands of times shorter than the time required for a human to do the same tasks interactively.

As with breakpoints, GDB assigns a number to each tracepoint when you create it. Like breakpoint numbers, tracepoint numbers are successive integers starting from one. Many of the commands associated with tracepoints use the tracepoint number to identify which tracepoint to delete, disable, etc.

A trace experiment must involve each of the following steps: defining the tracepoints and actions, running the experiment, and reviewing the results. Many of the commands defined below (such as setting and deleting tracepoints) have no real effect until you actually begin running the trace experiment. Moreover, many of them also have no effect during an already running trace experiment. Once a trace experiment is running, changing the tracepoints or their attributes will have no effect unles you stop the experiment and start it again.

Tracepoints are set with the trace command (abbreviated tr). The debugger convenience variable '$tpnum' records the tracepoint number of the most recently set tracepoint; see for a discussion of what you can do with convenience variables.

The location of a tracepoint can be specified in exactly the same ways as the location of a breakpoint, here reproduced for convenience.

trace func_name

Set a tracepoint at entry to function func_name. When using source languages that permit overloading of symbols, such as C++, func_name may refer to more than one possible place to trace. See for a discussion of that situation.

trace +offset

trace -offset

Set a tracepoint some number of lines forward or back from the "current location". Note that the "current location" is affected not only by stack walking commands such as up and down, but also by trace browsing commands such as tfind (see ).

trace linenum

Set a tracepoint at line linenum in the current source file. The current source file is the last file listed, or the last file in which execution stopped (eg. at a breakpoint), or the last file visited while browsing trace results (see ).

trace filename:linenum

Set a tracepoint at line linenum in source file filename.

trace filename:func_name

Set a tracepoint at entry to function func_name found in file filename. The filename is superfluous except when several source files contain functions with the same name.

trace *address

Set a tracepoint at address address. You can use this to set tracepoints in parts of your program which do not have debugging information or source files.

Some programming languages (notably C++) permit a single function name to be defined several times, for application in different contexts. This is called overloading. Tracepoints on overloaded functions behave exactly like breakpoints do (see "Breakpoint menus" in the GDB manual (available at )).

Any tracepoint's definition can be permanently discarded using the delete tracepoint command (abbreviated del tr). Give the tracepoint number(s) of the tracepoint(s) that you want to delete. A deleted tracepoint no longer exists, in contrast with a disabled tracepoint (which can be re-enabled). Use the info tracepoints command to discover the numbers of your tracepoints.

NOTE: this command has no effect on a running trace experiment.

delete tracepoint [tpnums...]

Delete the tracepoint(s) of the numbers specified as arguments. If no argument is specified, delete all tracepoints (GDB asks confirmation, unles you have set confirm off. You can abbreviate this command as del tr.

Rather than deleting a tracepoint, you might prefer to disable it. This will make the tracepoint inoperative in the next trace experiment, but remembers the tracepoint and all it's attributes so that you can enable it again. You disable and enable tracepoints with the disable tracepoint and enable tracepoint commands. Use the info tracepoints command to find out the numbers of tracepoints and which ones are enabled.

NOTE: these commands have no effect on a running trace experiment.

disable tracepoint [tpnums...]

Disable the specified tracepoints -- or all tracepoints if none are listed. A disabled tracepoint will have no effect in the next trace experiment, but is not forgotten. All its attributes are remembered, and will still be in effect if it is enabled again later. You can abbrevkate this command as dis tr.

enable tracepoint [tpnums...]

Enable the specified tracepoints (or all tracepoints). They will become effective again the next time a trace experiment is started. You can abbreviate this command as en tr.

Passcounts allow you to terminate a trace experiment automatically. If a tracepoint has a non-zero passcount of , then the trace experiment will automatically terminate (and no more trace data will be collected) when that tracepoint has been executed times.

Any number of tracepoints may have passcounts of any integer value. When the first tracepoint reaches its passcount, the trace experiment will terminate.

To clear a passcount, set it to zero.

NOTE: this command has no effect on a running trace experiment.

passcount <n> [tpnum]

Set the passcount of the given tracepoint to <n>. If tpnum is omitted, set the passcount of the most recently defined tracepoint. You can abbreviate this command as pas.

A tracepoint can do far more than simply record where your program has been. It can also save the values of selected program variables, machine registers, or memory locations for you to examine later at your leisure. All of these data go into a single buffer, but except for the size of that buffer there is virtually no limit to the data you can collect at tracepoints.

The actions at a tracepoint may also include single-stepping for some number of machine instructions, collecting data at each step. In this mode you can collect the changes in registers or variables over a range of instructions.

Here are the commands for defining the actions for a tracepoint.

actions [tpnum]

...action-list...

end

Specify a list of actions for tracepoint number tpnum. The actions themselves appear on the following lines. Type a line containing just end to terminate the actions. To remove all actions from a tracepoint, type actions [tpnum] and follow it immediately with end; that is, give no actions. With no tpnum argument, actions refers to the last tracepoint set.

collect [exprs]

Describes data to be collected at the tracepoint. Exprs may be any legal C expression, or several expressions separated by commas. Any global, static, or local variables may be collected. In addition, the following special arguments are supported.
  • $regs - collect all machine registers
  • $args - collect all arguments of the traced function
  • $locs - collect all local variables of the traced function

while-stepping <n>

	while-stepping <n>
collect [exprs]
end

After collecting any data requested at the tracepoint itself, execute <n> machine instructions, collecting the following expressions after each instruction. Each step will generate a separate trace event in the trace buffer (see ).

end

Terminates an action list, or a while-stepping collection list. If actions include stepping, two end commands are required.

NOTE: these commands have no effect on a running trace experiment.

Use this command to list all existing tracepoints and their attributes.

info tracepoints [tpnum]

Print a list of all tracepoints that have been set and not deleted, together with the following information for each tracepoint.
  • Tracepoint Number
  • Enabled or Disabled
    • Enabled tracepoints are marked with a 'y'; disabled tracepoints display 'n'.
  • Address
    • The memory address in your program of the tracepoint.
  • PassCount
    • If non-zero, the trace experiment will be terminated when this tracepoint has been hit this many times.
  • StepCount
    • If non-zero, the tracepoint will also execute this many machine instructions, collecting a trace event for each one.
  • What
    • Source file and line number of the tracepoint, if known.
  • Actions
    • Repeats the actions list for the tracepoint, as entered by the user.

None of the commands discussed so far will have any actual effect until you tell GDB to start a trace experiment. Only then will the tracepoints begin collecting data. Moreover, once you have started a trace experiment, none of the commands above have any effect on the running experiment. Changes to your tracepoints will only go into effect the next time you start a trace experiment. Therefore, if you delete, disable, enable, or define any new tracepoints, or change the actions or passcounts of existing tracepoints, you must stop any currently running trace collection experiment and start a new one before your changes will go into effect.

You start and stop trace collection by using the tstart and tstop commands.

tstart

Start trace data collection.

tstop

Stop trace data collection.

NOTE: trace data collection may also be stopped automatically if any tracepoint's passcount is reached. It may also stop automatically if the trace buffer becomes full, unles the trace buffer is set to operate in a continuous "circular buffer" mode.

Note also that starting trace collection has the side effect of discarding any old trace data in the buffer, so that the buffer starts out empty each time. You may stop a trace experiment and still look at your saved data, but as soon as you start a new trace experiment, the previously collected data will be irretrievably gone.

While a trace experiment is running, every time a tracepoint is executed generates a trace event, and every trace event generates a data record called a trace frame in a buffer called the trace buffer. If a tracepoint's actions include single-stepping, each single-step also generates a trace event and a trace frame.

Each trace frame has a sequential identifying number starting from zero, plus the address (PC) of the event. In addition, the trace frame contains any values collected by the actions for the corresponding tracepoint.

The basic commands for selecting a trace frame and extracting data from it are tfind and tdump. In addition, several built-in GDB variables are provided for identifying the currently selected trace frame.

tfind [< event id > | start | none | -]

Select a trace frame (event) by id number. "tfind start" is a synonym for tfind 0 (where zero is the lowest numbered trace frame). If no argument is specified, selects the next frame. "tfind -" selects the previous frame, and "tfind none" selects no frame.

tfind tracepoint [< tracepoint id >]

Select the next trace frame (event) corresponding to the given tracepoint. If no argument is given, find the next trace frame corresponding to the same tracepoint as the current frame.

tfind pc [< address >]

Select the next trace frame corresponding to the given code address. If no argument is given, find the next trace frame corresponding to the same PC as the current frame.

tfind line [linenum]

tfind line [filename:linenum]

Select the next trace frame corresponding to the given source line. If no argument is given, then advance to the next trace frame from any source line other than the current one. This is useful when a trace frame is collected for every machine instruction. It has the effect of advancing past all the events for instructions in the current source line, thus getting to the next line traced.

tdump

Print all of the data collected at the current trace frame.



However, many people find that the most useful way to review the
collected data is interactively.  Whenever you use the tfind
command, GDB displays the source line corresponding to the selected
trace frame, just as if you had stepped to that line or hit a
breakpoint there.  The next tfind command takes you to the next source
line, very much like stepping.  At each trace frame, you can use all
of the customary GDB commands to examine the data collected, very much
as you could if you were sitting at a breakpoint, except that you can
only examine values that you collected earlier by listing them in the
action lists of your tracepoints.  


Once you have defined a set of tracepoints and actions, you may want to save them to be used later in another debug session. The save-trace command saves all tracepoints, passcounts and actions as a GDB command file, which can be imported later by using the source command (See "Command files" in the GDB manual (available at )).

save-tracepoints filename

Write all tracepoint definitions, passcounts, and actions out to the command file 'filename', suitable for reading with the source command.
阅读(1527) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~