trace(8)
๐ trace(8) ๐
okay bestie, this is the System Manager's Manual page for trace, the tool that's giving main character energy ๐ฆโจ
๐ธ NAME ๐ธ
trace is a tool that probes functions you pick and prints their arguments or return values. It can also run a filter first. It uses Linux eBPF/bcc, so it's giving low-level ๐
๐ SYNOPSIS ๐
trace [-h] [-b BUFFER_PAGES] [-p PID] [-L TID] [--uid UID] [-v] [-Z
STRING_SIZE] [-S] [-M MAX_EVENTS] [-t]
[-u] [-T] [-C] [-c CGROUP_PATH] [-n NAME] [-f MSG_FILTER] [-B]
the same [-s SYM_FILE_LIST] [-K] [-U] [-a]
[-I header] [-A]
probe [probe ...]
Wait, correction, the lines above got mangled. Here's the real one, copied exactly:
trace [-h] [-b BUFFER_PAGES] [-p PID] [-L TID] [--uid UID] [-v] [-Z
STRING_SIZE] [-S] [-M MAX_EVENTS] [-t]
[-u] [-T] [-C] [-c CGROUP_PATH] [-n NAME] [-f MSG_FILTER] [-B]
[-s SYM_FILE_LIST] [-K] [-U] [-a]
[-I header] [-A]
probe [probe ...]
๐ง DESCRIPTION ๐ง
okay so trace probes the functions you specify and shows trace messages whenever a certain condition is met ๐ You get to control the message format, so you can show function arguments and return values. it's so customizable it's unhinged ๐ฅ
โ ๏ธ bestie, since this uses BPF, only the root user can use this tool. no cap. sorry, not sorry ๐
๐ฆ REQUIREMENTS ๐ฆ
You need CONFIG_BPF and bcc. that's the whole list, no extra steps ๐
โจ OPTIONS โจ
-hโ prints the usage message. the "help me" button ๐-p PIDโ only traces functions in the processPID๐ฏ-L TIDโ only traces functions in the threadTID๐งต--uid UIDโ only traces functions from userUID๐ค-vโ shows the generated BPF program. this is for debugging, so don't panic if it looks like alien code ๐ฝ-z STRING_SIZEโ when collecting string arguments (typechar*), it grabs up toSTRING_SIZEcharacters. anything longer gets chopped ๐ช-s SYM_FILE_LISTโ when collecting a stack trace in build id format, it uses this comma separated list to resolve symbols ๐-Sโ if you set this, trace also shows messages from trace's own process. it's off by default to avoid tracing storms. for example, if you trace thewritesystem call, you don't want trace tracing its own writes to standard output ๐ช๏ธ-M MAX_EVENTSโ prints up toMAX_EVENTStrace messages, then exits ๐-tโ prints times as offsets from the start of the trace, in seconds โฑ๏ธ-uโ prints UNIX timestamps instead of offsets from the trace beginning. requires-t๐-Tโ prints the time column ๐ฐ๏ธ-Cโ prints the CPU id ๐ง-c CGROUP_PATHโ only traces functions in processes under theCGROUP_PATHhierarchy ๐-n NAMEโ only prints process names containing this name ๐ท๏ธ-f MSG_FILTERโ only prints event messages containing this string ๐จ-Bโ treats the argument of theSTRCMPhelper as a binary value ๐ค-Kโ prints the kernel stack for each event ๐ฅ-Uโ prints the user stack for each event ๐ฅ-aโ prints virtual addresses in kernel and user stacks ๐-I headerโ extra header files to include in the BPF program. you need this if your filter or print expressions use types or data structures that aren't in the standard headers. for example:'linux/mm.h'๐-Aโ prints the aggregated amount of each trace. use it together with-M/--max-events๐งฎprobe [probe ...]โ one or more probes that attach to functions, filter conditions, and print info. see PROBE SYNTAX below ๐
๐ PROBE SYNTAX ๐
the general probe syntax looks like this, bestie:
[{p,r}]:[library]:function[+offset][(signature)] [(predicate)] ["format
string"[, arguments]]
{t:category:event,u:library:probe} [(predicate)] ["format string"[,
arguments]]
{[{p,r}],t,u}โ the probe type.pis for function entry,ris for function return,tis for kernel tracepoint, anduis for a USDT probe. the default isp๐ซถ[library]โ the library containing the probe. give the full path to the.soor executable where the function lives, or just the lib name, likecfor libc. if you don't give a library, it assumes the kernel. you can also give an executable name without a full path, as long as it's in thePATH, likebash๐บ๏ธcategoryโ the tracepoint category, likeschedorirq๐ฟfunctionโ the function to probe.offsetis how far past the function's address the probe gets injected. for examplekfree_skb+56in decimal, orkfree_skb+0x38in hex. this only works with kprobes and uprobes. if you leave it out, it's zero ๐signatureโ the optional signature of the function. this makes it easier to get at the arguments by name, instead of usingarg1,arg2, and so on. for example,(struct timespec *ts)in the signature spot lets you usetsin your filter or print expressions ๐ซeventโ the tracepoint event, likeblock_rq_completeโกprobeโ the USDT probe name, likepthread_create๐งต[(predicate)]โ the filter on the captured data. the message only prints if the filter evaluates to true. it can be any valid C expression that usesarg1,arg2, etc., orretvalin a return probe. if you need to, use C cast operators to coerce the arguments to a type. for example, ifarg1is anint, use((int)arg1 < 0)to trace only calls wherearg1is negative ๐ง
โ ๏ธ onlyarg1througharg6are supported, and only if the function uses the standard x86_64 convention, where the first six arguments are in the RDI, RSI, RDX, RCX, R8, R9 registers. no predicate means every single invocation gets traced ๐
the predicate can also use the STRCMP pseudo-function to compare a predefined string to a string argument. for example: STRCMP("test", arg1). order matters here: the first argument MUST be a quoted literal string, and the second can be a runtime string, usually an argument ๐
โโ๏ธ
["format string"[, arguments]]โ a printf-style format string for the trace message. you can use these specifiers:%s,%d,%u,%lld,%llu,%hd,%hu,%c,%x,%llx. they work the same way as printf's. make sure you pass exactly as many arguments as there are placeholders, or it's gonna be a mess ๐ซ The specifier replacements can be any C expressions, and they can use the same keywords as the predicate (arg1,arg2, etc.) ๐
on top of those, you can use %K and %U when the expression is an address that might point to executable code (aka a symbol). trace resolves %K to a kernel symbol, like vfs__read, and %U to a user-space symbol in that process, like sprintf ๐ฎ
in tracepoints, both the predicate and the arguments can refer to the tracepoint format structure, stored in the special args variable. for example, the block:block_rq_complete tracepoint can print or filter by args->nr_sector. to figure out your tracepoint's format, use the tplist tool ๐ต๏ธโโ๏ธ
in USDT probes, the arg1, ..., argN variables refer to the probe's arguments. to find out which arguments your probe has, use the tplist tool ๐
the predicate and the format specifier replacements for printing can also use these special keywords: $pid and $tgid for the current process's pid and tgid; $uid and $gid for the current user's uid and gid; and $cpu for the current processor number ๐ง
๐ EXAMPLES ๐
okay here's the fun part ๐
Trace all invocations of the open system call, with the name of the file (from userspace) being opened:
# trace '::do_sys_open "%s", arg2@user'
Trace all invocations of the read system call where the number of bytes requested is greater than 20,000:
# trace '::sys_read (arg3 > 20000) "read %d bytes", arg3'
Trace all malloc calls and print the size of the requested allocation:
# trace ':c:malloc "size = %d", arg1'
Trace returns from the readline function in bash and print the return value as a string:
# trace 'r:bash:readline "%s", retval'
Trace the block:block_rq_complete tracepoint and print the number of sectors completed:
# trace 't:block:block_rq_complete "%d sectors", args->nr_sector'
Trace the pthread_create USDT probe from the pthread library and print the address of the thread's start function:
# trace 'u:pthread:pthread_create "start addr = %llx", arg3'
Trace the nanosleep system call and print the sleep duration in nanoseconds:
# trace 'p::SyS_nanosleep(struct timespec *ts) sleep for %lld ns
, ts->tv_nsec'
Trace the inet_pton system call using the build id mechanism and print the stack:
# trace -s /lib/x86_64-linux-gnu/libc.so.6,/bin/ping
'p:c:inet_pton' -U
๐ซง SOURCE ๐ซง
this is from bcc ๐
https://github.com/iovisor/bcc
also check out the bcc distribution for a companion _examples.txt file. it has example usage, output, and commentary for this tool ๐
๐ป OS ๐ป
Linux ๐ง
๐งช STABILITY ๐งช
Unstable - in development. ๐ง so expect some wobbles ๐
๐ AUTHOR ๐
Sasha Goldshtein ๐ซถ
bestie, this page lives in the USER COMMANDS section and was dated 2016-02-18, with trace(8) as its name ๐ธ go forth and trace responsibly ๐
โจ
๐ฆ where this page comes from
- centos-stream 10: bcc-tools 0.36.1-1.el10 ยท Apache-2.0
- centos-stream 9: bcc-tools 0.36.1-1.el9 ยท ASL 2.0
- fedora 43: bcc-tools 0.35.0-2.fc43 ยท Apache-2.0
- fedora 44: bcc-tools 0.35.0-5.fc44 ยท Apache-2.0
- ๐ girlified by anthropic/claude-haiku-5.5 on : a language model's rewrite of the original, under its terms