ftrace — trace system calls, function calls and signals
ftrace
[-c] [-dl] [-m] [-o=FILE
] [-p=PID
...] [-pc] [-sys=SYSCALL
[,SYSCALL
...]] [-sig=SIG
[,SIG
...]] [-sym=RULE
[,RULE
...]] [-addr=RULE
[,RULE
...]] [-stack] [--] command
[arguments
...]
ftrace
starts given
command
and according to tracing script
given via command-line arguments, it traces its system calls,
symbol entry points in general, and possibly other events as well.
It uses the Frysk framework to implement tracing.
The working set of events ftrace
should
trace is defined by the following arguments.
PID
Attach to a process with given
PID
.
Trace children: automatically attach to forks of traced process.
Trace inside dynamic linker. When this option is
not present, ftrace
will function
as if -#INTERP#* rule was present at the end of each
tracing script.
SYMBOL
[,SYMBOL
...]Trace calls through the symbol entry points. Ftrace displays a message each time a thread of execution hits entry point of one of the traced functions, and then when (if) the function returns.
If SYMBOL
references
PLT slot, calls done through that PLT slot are recorded.
You then effectively trace calls done FROM given library
or executable, and generally can't say which library the
call leads TO.
When tracing ordinary symbol, catch all calls that end up at this symbol. That includes the calls that don't go through PLT and as such are not intended as inter-library calls, but rather intra-library calls.
See below for detailed description of
SYMBOL
rule syntax.
SYSCALL
[,SYSCALL
...]Trace system calls that match given
SYSCALL
ruleset. See
below for description of
SYSCALL
syntax.
SIGNAL
[,SIGNAL
...]Trace signals that match given
SIGNAL
ruleset. See
below for description of
SIGNAL
syntax.
RULE
[,RULE
...]Trace addresses given by
RULE
s. See below for
description of address RULE
syntax.
Print each file mapped to or unmapped from address space of the traced process.
Show the value of instruction pointer at each reported event.
Stack trace when traced symbol is hit. Note that this option also applies to traced system calls. If you need to cherry-pick which event should stack trace, use # operator described in sections below.
-number-of-frames count
Limit the back-trace to count
frames. The default is to limit the back-trace to 10
frames. Specify 0 or "all" to print all
frames.
-lite
Perform a light-weight stack backtrace containing only minimal information. Equivalent to -print -.
-rich
Perform a detailed stack back-trace that includes, where possible, inlined function calls, parameter names and values, and debug-names. Equivalent to -print inline,params,debug-names.
-print print-option
,...
Specify the level of detail to include in a stack
back-trace. print-option
can be
any of:
debug-names: use debug information, such as DWARF, to determine the name of functions
paths: include the full path to source files and libraries
inline: include in-line function in back-trace
locals: to include local variables from each frame
params: include the function parameters
To negate a print-option
prefix
it with "-".
-exe
The full path of the executable to read.
-noexe
Do not attempt to read the corresponding executable when loading a core file.
-sysroot directory
The system root directory under which all executables, libraries, and source are located.
-debug class
=level
...
Set internal debug-tracing of the specified
Java class
to level
(level can be NONE,
INFO, WARNING, FINE, and FINEST). If
the level
is absent, FINE is
assumed; if the class
is absent,
the global level is set.
To decide which PLT slots or entry points should be traced, following process takes place. A set of symbols to trace ("working set") is initially empty. Rules, if present, are then enumerated from left to right, and set is modified depending on the rules. Rules are delimited by a comma. Syntax of each rule is following:
[-]pattern
[/options
]
Without the optional "-" all symbols that match
the pattern
are added to the working
set. With "-", matching symbols are removed.
If "/" is present at the end of the rule, following letters are interpreted as rule flags. Currently only one flag is available, "s". When present, it means ftrace should show a stack trace when it hits a symbol that matches this rule.
When a "-" rule has an "/s" flag, the call should still be traced, but stack trace shouldn't be generated.
pattern
defines which symbols or
PLT slots from which libraries should be added or removed from
working set. Syntax of pattern is as follows:
[#soname
#][filename.c
#][(proc
|line
)#][plt:]symbol[@version
]
soname
component is matched
against a soname of a library in which we wish to trace the call.
If the library has no associated soname (such as is usual in case
of main executable), the match is done against the file name
(without a path). Two special sonames are distinguished: "MAIN",
which always matches main executable; and "INTERP", which always
matches ELF interpreter (dynamic linker) of the main executable.
If the component is missing, then the rule is applicable in all
libraries and in main executable.
filename.c
component is matched
against the name of a file where the symbol is defined. NOTE:
This is currently not implemented.
proc
component is matched against
the name of block surrounding the definition we wish to trace. If
the block doesn't have a name, you can instead refer to it with
the line
number that the block
surrounds. NOTE: This is currently not implemented.
symbol
component is matched
against the name of symbol under consideration. If
"plt:" prefix is present, the rule matches PLT entry
associated with the symbol instead of the symbol itself.
version
component is matched
against version associated with symbol. If the symbol has no
associated version, it is considered to be an empty string. (It
is possible to request symbol without a version with the pattern
"foo@".) NOTE: This is currently not implemented.
All components are presented in glob syntax. See glob(7) manual page for more details. See below for examples.
Under the presence of the -sys
(or
-sig
) option, ALL system calls (or signals) are
ALWAYS traced. This is a limitation of the ptrace layer. The
system call and signal rules however serve as a simple way of
filtering out the output that you are not interested in. In
following paragraphs, the word "event" will be used to
mean "signal or syscall, whatever applies".
The system call and signal rule syntax and semantics are the same as the symbol rule syntax:
[-]pattern
[/options
]
Event selection pattern syntax is then as follows:
[event name
|event number
]
When the pattern is empty, it matches all events known to frysk. When the pattern is simple number (e.g. "12"), then the pattern matches the event with the given number. Otherwise the pattern is considered to be case-insensitive glob, and matched against event names. Whole name has to match for event to be a part of working set.
Signal can be given both with and without leading "sig" (e.g. "sigkill" as well as "kill").
The process of establishing a working set of addresses that should be traced is the same as for symbol rules, and the general syntax reflects that. Each rule looks like this:
[-]pattern
[/options
]
Each pattern then looks like this:
[#soname
#][0x]address
Addresses are always given in hexadecimal notation, even if initial 0x is missing.
soname
component is the same as
in symbol tracing, i.e. it's matched against a soname of a library
in which we wish to trace the address. Same rules apply regarding
INTERP and MAIN meta-sonames. Refer to the chapter "SYMBOL RULE
SYNTAX" for detailed description.
Even though soname
is optional,
at least one soname has to be specified at the beginning of the
-addr
command. That's because in general it
makes no sense to want to trace the same address in ALL object
files at once. The components that are soname-less are assumed to
have a soname of the previous component that has soname.
For example, this will trace two addresses from the main binary, and stack trace one of them:
ftrace -addr=#MAIN#0x08052780/s,08049314 -- ls
If you need to trace the same address in several files, you can use the fact that the soname pattern is a glob.
The addresses are assumed to be copied from readelf or objdump. ftrace biases the value accordingly depending on where the module is actually mapped.
Trace all system calls:
ftrace -sys= ls
Trace variants of stat system call and moreover a system call #3:
ftrace -sys='*stat*,3' ls
Various ways to tell ftrace that you want to stack trace on SIGUSR1:
ftrace -sig=USR1/s,usr1/s,SIGUSR1/s,sigusr1/s,10/s ~/sig
Trace all library calls:
ftrace -sym=plt:* ls
Trace all library calls to functions that contain substring "write" in their names:
ftrace -sym=plt:*write* ls
Trace memory functions done from libraries, i.e. not from main executable:
ftrace -sym='plt:*alloc,plt:free,-#MAIN#plt:*' ls
Stack trace on everything, except for memory allocation functions (which should still be traced):
ftrace -sym='plt:*/s,-plt:*alloc/s,-plt:free/s' ls
The option parser is greedy when looking for options so running ftrace on a program that uses options can be a problem, use -- to split between ftrace and the program. So change from:
~/prefix/bin/ftrace ~/prefix/lib64/frysk/funit --arch 32 frysk.proc.TestAbandon
to
~/prefix/bin/ftrace -- ~/prefix/lib64/frysk/funit --arch 32 frysk.proc.TestAbandon
Report bugs to http://sourceware.org/frysk