FTRACE(1)

πŸ“¦ version 0.4, in fedora 43, fedora 44

πŸ’… FTRACE(1) β€” aka the Frysk one, bestie

okay so real talk, this is ftrace, it lives in the Frysk manual (section 1, the command-line-girlies section πŸ’–), and it is genuinely iconic. It traces your system calls, your function calls, your signals β€” the whole vibe. Let's get into it.


✨ NAME ✨

ftrace β€” trace system calls, function calls and signals. that's it, that's the whole job, and it slays at it 🫢


✨ SYNOPSIS ✨

ftrace [-f] [-follow] [-dl] [-m] [-o=FILE] [-p=PID...] [-pc]
       [-sys=SYSCALL[,SYSCALL...]] [-sig=SIG[,SIG...]]
       [-sym=RULE[,RULE...]] [-addr=RULE[,RULE...]] [-stack] [--]
       command [arguments...]

✨ DESCRIPTION ✨

So here's the tea: ftrace starts up whatever command you hand it, and then β€” based on the tracing script you built out of command-line arguments β€” it traces that program's system calls, its symbol entry points in general, and honestly possibly other events too. She's flexible like that. πŸ’β€β™€οΈ

Under the hood she's running on the Frysk framework to make the tracing happen. No cap.

The working set of events that ftrace should trace gets defined by the arguments below. Think of it like a guest list for the function party β€” you add people, you remove people, and whoever's left gets traced. πŸŽ€


🫢 Process Selection Options

  • -p=PID β€” attach to a process with the given PID. Like sliding into someone's DMs but for tracing. πŸ‘€
  • -f, -follow β€” follow children: automatically attach to forks of the traced process. every baby process gets an invite too, fr fr 🍼

πŸ¦‹ Symbol Tracing

  • -dl β€” trace inside the dynamic linker. And here's the important part bestie: when this option is not present, ftrace will function as if a -#INTERP#* rule was present at the end of each tracing script. so like, it's lowkey always kinda there unless you say otherwise. ✨
  • -sym=SYMBOL[,SYMBOL...] β€” trace calls through the symbol entry points. ftrace displays a message every single time a thread of execution hits the entry point of one of the traced functions, and then again when (if) that function returns. two messages, one function, main character energy. πŸ’…

If SYMBOL references a PLT slot, then calls done through that PLT slot are recorded. Which means you're effectively tracing calls done FROM a given library or executable, and generally you can't say which library the call leads TO. that's just how it is, sorry babe 😭

When tracing an ordinary symbol, you 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. she's thorough, okay?!

See below for the detailed description of SYMBOL rule syntax. πŸ‘‘


🌈 Other Traceable Events

  • -sys=SYSCALL[,SYSCALL...] β€” trace system calls that match the given SYSCALL ruleset. See below for the description of SYSCALL syntax. 🐧
  • -sig=SIGNAL[,SIGNAL...] β€” trace signals that match the given SIGNAL ruleset. See below for the description of SIGNAL syntax. πŸ“‘
  • -addr=RULE[,RULE...] β€” trace addresses given by RULEs. See below for the description of address RULE syntax. πŸ“

πŸŽ€ Other Options

  • -m β€” print each file mapped to or unmapped from the address space of the traced process. memory map gossip, we love to see it πŸ—ΊοΈ
  • -pc β€” show the value of the instruction pointer at each reported event. where are we? exactly there. πŸ“Œ
  • -stack β€” stack trace when a traced symbol is hit. And heads up: this option also applies to traced system calls. If you need to cherry-pick which event should stack trace, use the # operator described in the sections below. πŸ’

⭐ Stack Print Options

  • -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. no holding back, give me the whole lore πŸ“š
  • -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. she's giving depth 🧚
  • -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 "-". 🚫


πŸ’œ Standard Frysk Options

  • -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. πŸ›

πŸ‘‘ SYMBOL RULE SYNTAX πŸ‘‘

okay so how does she decide which PLT slots or entry points should be traced? The following process takes place. A set of symbols to trace (the "working set") starts out empty. Rules, if present, are then enumerated from left to right, and the set is modified depending on the rules. Rules are delimited by a comma. Syntax of each rule is the following:

[-]pattern[/options]

Without the optional "-", all symbols that match the pattern are added to the working set. With "-", matching symbols are removed. it's giving plus-one / minus-one 🎟️

If "/" is present at the end of the rule, the 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 a stack trace shouldn't be generated. sneaky but fair.

pattern defines which symbols or PLT slots from which libraries should be added or removed from the 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 the case of the main executable), the match is done against the file name (without a path). Two special sonames are distinguished: "MAIN", which always matches the main executable; and "INTERP", which always matches the ELF interpreter (dynamic linker) of the main executable. If the component is missing, then the rule is applicable in all libraries and in the 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 the 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 the symbol under consideration. If a "plt:" prefix is present, the rule matches the PLT entry associated with the symbol instead of the symbol itself. 🎯
  • version component is matched against the version associated with the symbol. If the symbol has no associated version, it is considered to be an empty string. (It is possible to request a 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. πŸ’–


πŸ“‘ SYSCALL AND SIGNAL RULE SYNTAX πŸ“‘

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 the 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 a simple number (e.g. "12"), then the pattern matches the event with the given number. πŸ”’
  • Otherwise the pattern is considered to be a case-insensitive glob, and matched against event names. The whole name has to match for the event to be a part of the working set. βœ…

Signal can be given both with and without a leading "sig" (e.g. "sigkill" as well as "kill"). both are valid, she's not picky πŸ’…


πŸ“ ADDRESS RULE SYNTAX πŸ“

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 the initial 0x is missing. just trust the process ✨

The 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. The same rules apply regarding the INTERP and MAIN meta-sonames. Refer to the chapter "SYMBOL RULE SYNTAX" for a 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 the soname of the previous component that has a 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. 🧭


πŸ”₯ EXAMPLES πŸ”₯

Trace all system calls:

ftrace -sys= ls

Trace variants of the 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 the substring "write" in their names:

ftrace -sym=plt:*write* ls

Trace memory functions done from libraries, i.e. not from the 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

🌸 SEE ALSO 🌸

frysk(7), glob(7) β€” go read them, they're the supporting cast and they ate πŸ’–


πŸ’€ BUGS πŸ’€

okay so, 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 πŸ›


and that's the whole page bestie 🫢 this was Frysk 0.4-99.fc43, dated April 2008 β€” yes she's an elder millennial, she's still that girl, periodt πŸ’…βœ¨

πŸ“¦ where this page comes from
  • fedora 43: frysk 0.4-99.fc43 Β· GPL-2.0-only WITH 389-exception AND GPL-2.0-or-later WITH Classpath-exception-2.0 AND MIT
  • fedora 44: frysk 0.4-99.fc43 Β· GPL-2.0-only WITH 389-exception AND GPL-2.0-or-later WITH Classpath-exception-2.0 AND MIT
  • πŸ’– girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms