argdist(8)
โจ argdist(8) โ bestie's guide to argdist โจ
๐ธ NAME ๐ธ
argdist - Okay so this one traces a function and shows you a histogram or frequency count of its parameter values. It's Linux eBPF/bcc, so it's giving low-level main character energy ๐
๐ SYNOPSIS ๐
argdist [-h] [-p PID] [-z STRING_SIZE] [-i INTERVAL] [-d DURATION] [-n COUNT] [-v] [-T TOP] [-H specifier] [-C specifier] [-I header] [-t TID]
๐ DESCRIPTION ๐
Okay bestie, argdist attaches to function entry and exit points, grabs the parameter values you care about, and stashes them in either a histogram or a frequency collection. The frequency one counts how many times each parameter value showed up ๐ It can also filter the values, and it can instrument multiple entry points at once โจ
Since this runs on BPF, only the root user can use this tool. No root, no argdist, sorry bestie ๐
๐ง REQUIREMENTS ๐ง
You'll need CONFIG_BPF and bcc. Make sure you've got both before you try to slay with it ๐ฅ
๐ OPTIONS ๐
-hโ Prints the usage message ๐-p PIDโ Only traces functions in the processPID๐ฏ-t TIDโ Only traces functions in the threadTID๐งต-z STRING_SIZEโ When you're collecting string arguments (typechar*), it grabs up toSTRING_SIZEcharacters. Anything longer gets truncated, so it's not gonna be the full tea ๐ต-i INTERVALโ Prints the collected data everyINTERVALseconds. The default is 1 second โฑ๏ธ-d DURATIONโ The total duration of the trace, in seconds โ-n NUMBERโ Prints the collected dataCOUNTtimes and then exits. Bye bye ๐-vโ Shows the generated BPF program, for debugging purposes. Nerd mode activated ๐ค-T TOPโ When you're collecting frequency counts, it only displays the topTOPentries. Only the best of the best ๐-H specifiers,-C specifiersโ One or more probe specifications that tell argdist which functions to probe, which parameters to collect, how to aggregate them, and whether to filter anything. See SPECIFIER SYNTAX below ๐-I headerโ One or more header files to include in the BPF program. This lets you use structure definitions, enumerations, and constants from those headers. Use the same path you'd include in the BPF program, like'linux/blkdev.h'or'linux/time.h'. Note: in lots of cases, argdist will figure out the needed header files on its own ๐ซถ
๐ฆ SPECIFIER SYNTAX ๐ฆ
Okay so the general specifier syntax looks like this, and yes it's a lot, but we're gonna break it down together ๐ฅน
{p,r,t,u}:{[library],category}:function(signature):type[,type...]:expr[,expr...][:filter]][#label]
{p,r,t,u}
This is the probe type. p is for function entry, r is for function return, t is for a kernel tracepoint, and u is for a USDT probe. It's also where you pick -H for a histogram or -C for a frequency count. It tells argdist where to put the probe and whether to collect a frequency count or stuff the values into a histogram. Counting probes record how many times each parameter value was seen, while histogram probes put the parameter values into a histogram. Only integral types work with histogram probes. Counting probes have no such limit, so they're more chill ๐
[library]
This is the library that contains the probe. Give the full path to the .so or executable where the function lives. Or, if you're lazy (no judgment), just give the lib name. For example, "c" means libc. If you don't name a library, argdist assumes the kernel ๐ง
category
The category of the kernel tracepoint. For example: net, sched, block ๐๏ธ
function(signature)
The function to probe, plus its signature. The function name has to match exactly or the probe won't get placed, so no typos bestie ๐
. The signature is only needed if you want to collect parameter values based on it. If you only want the first parameter, you don't have to list the rest. For kernel tracepoints, this should be the name of the event, like net_dev_start_xmit, and the signature should be empty. For USDT probes, this should be the name of the probe, like reloc_complete, and the signature should also be empty ๐ซ
[type[,type...]]
The type(s) of the expression(s) you're capturing. These are the types of the keys in the histogram or raw event collection the probes collect ๐
[expr[,expr...]]
The expression(s) to capture. These are the values that get assigned to the histogram or raw event collection. You can use the parameters directly, or valid C expressions that use them, like "size % 10". Tracepoints can access a special structure called "args", which is formatted according to the tracepoint format (you can grab that with tplist). For example, the block:block_rq_complete tracepoint can access args->nr_sector. USDT probes can access the arguments the tracing program defines through the special arg1, arg2, ... variables. To find their types, use the tplist tool ๐ง
Return probes can use the argument values the function received when it was entered, through the $entry(paramname) special variable. They can also access the function's return value in $retval, and the function's execution time in nanoseconds in $latency. Heads up though: adding $latency or $entry(paramname) to the expression adds an extra probe at the function's entry to collect that data, so it adds extra overhead ๐ข
[filter]
The filter applied to the captured data. Only parameter values that pass the filter get collected. It's any valid C expression that refers to the parameter values, like "fd == 1 && length > 16". The $entry, $retval, and $latency variables work here too, in return probes. The filter can also use the STRCMP pseudo-function to compare a predefined string to a string argument, like STRCMP("test.txt", file). Argument order matters here: the first argument MUST be a quoted literal string, and the second can be a runtime string ๐งถ
[label]
The label that shows up when the probed values get printed. By default, it's the probe specifier itself ๐ท๏ธ
๐จ EXAMPLES ๐จ
Okay, now the fun part! Here are the examples, bestie ๐ฅณ
Print a histogram of allocation sizes passed to kmalloc:
# argdist -H 'p::__kmalloc(u64 size):u64:size'
Print a count of how many times process 1005 called malloc with an allocation size of 16 bytes:
# argdist -p 1005 -C 'p:c:malloc(size_t size):size_t:size:size==16'
Snoop on all strings returned by gets():
# argdist -C 'r:c:gets():char*:$retval'
Print a histogram of read sizes that were longer than 1ms:
# argdist -H 'r::__vfs_read(void *file, void *buf, size_t count):size_t:$entry(count):$latency > 1000000'
Print frequency counts of how many times writes were issued to a particular file descriptor number, in process 1005:
# argdist -p 1005 -C 'p:c:write(int fd):int:fd'
Print a histogram of error codes returned by read() in process 1005:
# argdist -p 1005 -H 'r:c:read()'
Print a histogram of buffer sizes passed to write() across all processes, where the file descriptor was 1 (STDOUT):
# argdist -H 'p:c:write(int fd, const void *buf, size_t count):size_t:count:fd==1'
Count fork() calls in libc across all processes, grouped by pid:
# argdist -C 'p:c:fork():int:$PID;fork per process'
Print a histogram of the number of sectors in completing block I/O requests:
# argdist -H 't:block:block_rq_complete():u32:nr_sector'
Aggregate interrupts by interrupt request (IRQ):
# argdist -C 't:irq:irq_handler_entry():int:irq'
Print the functions used as thread entry points and how common they are:
# argdist -C 'u:pthread:pthread_start():u64:arg2' -p 1337
Print histograms of sleep() and nanosleep() parameter values:
# argdist -H 'p:c:sleep(u32 seconds):u32:seconds' -H 'p:c:nanosleep(struct timespec *req):long:req->tv_nsec'
Spy on writes to STDOUT performed by process 2780, up to a string size of 120 characters:
# argdist -p 2780 -z 120 -C 'p:c:write(int fd, char* buf, size_t len):char*:buf:fd==1'
Group files being read from and the read sizes from __vfs_read:
# argdist -C 'p::__vfs_read(struct file *file, void *buf, size_t count):char*,size_t:file->f_path.dentry->d_iname,count:file->f_path.dentry->d_iname[0]!=0'
๐ SOURCE ๐
This one's from bcc ๐ซง
https://github.com/iovisor/bcc
Also, go check the bcc distribution for a companion _examples.txt file. It has example usage, output, and commentary for this tool, and it's honestly so helpful ๐
๐ฆ OS ๐ฆ
Linux ๐ง
๐ฎ STABILITY ๐ฎ
Unstable - in development. So it's a work in progress, bestie ๐ง
๐ AUTHOR ๐
Sasha Goldshtein ๐
Okay bestie, that's the whole tea โ This page is from the USER COMMANDS section, dated 2016-02-11, and it's argdist(8) being iconic as always ๐ฉทโจ
๐ฆ where this page comes from
- alpine 3.24: bcc-doc 0.36.1-r1 ยท Apache-2.0
- nixpkgs unstable: bcc 0.37.0
- opensuse-leap 16.0: bcc-tools 0.35.0-160000.2.2 ยท Apache-2.0
- opensuse-leap 16.0: bcc-tools 0.35.0-160000.2.2 ยท Apache-2.0
- opensuse-leap 16.0: bcc-tools 0.35.0-160000.2.2 ยท Apache-2.0
- opensuse-leap 16.0: bcc-tools 0.35.0-160000.2.2 ยท Apache-2.0
- ๐ girlified by anthropic/claude-haiku-5.5 on : a language model's rewrite of the original, under its terms