For a reference summary, see the [README.md](../README.md) for the sections on [Probe types](../README.md#probe-types) and [Builtins](../README.md#builtins).
This is a work in progress. If something is missing or incomplete, check the bpftrace source to see if these docs are just out of date. And if you find something, please file an issue or pull request to update these docs.
This is a work in progress. If something is missing, check the bpftrace source to see if these docs are just out of date. And if you find something, please file an issue or pull request to update these docs. Also, please keep these docs as terse as possible to maintain it's brevity (inspired by the 6-page awk summary from page 106 of [v7vol2b.pdf](https://9p.io/7thEdMan/bswv7.html)). Leave longer examples and discussion to other files in /docs, the /tools/\*\_examples.txt files, or blog posts and other articles.
The syntax to this program will be explained in the [Language](#language) section. In this section, we'll cover tool usage.
A program will continue running until Ctrl-C is hit, or an `exit()` function is called. When a program exits, all populated maps are printed: this behavior, and maps, are explained in later sections.
## 2. `-e 'program'`: One-Liners
The `-e` option allows a program to be specified, and is a way to construct one-liners:
```
# bpftrace -e 'tracepoint:syscalls:sys_enter_nanosleep { printf("%s is sleeping.\n", comm); }'
Attaching 1 probe...
iscsid is sleeping.
irqbalance is sleeping.
iscsid is sleeping.
iscsid is sleeping.
[...]
```
This example is printing when processes call the nanosleep syscall. Again, the syntax of the program will be explained in the [Language](#language) section.
## 3. `filename`: Program Files
Programs saved as files are often called scripts, and can be executed by specifying their file name. We'll often use a `.bt` file extension, short for bpftrace, but the extension is ignored.
For example, listing the sleepers.bt file using `cat -n` (which enumerates the output lines):
```
# cat -n sleepers.bt
1 tracepoint:syscalls:sys_enter_nanosleep
2 {
3 printf("%s is sleeping.\n", comm);
4 }
```
Running sleepers.bt:
```
# bpftrace sleepers.bt
Attaching 1 probe...
iscsid is sleeping.
iscsid is sleeping.
[...]
```
## 4. `-l`: Listing Probes
Probes from the tracepoint and kprobe libraries can be listed with `-l`.
```
# bpftrace -l | more
tracepoint:xfs:xfs_attr_list_sf
tracepoint:xfs:xfs_attr_list_sf_all
tracepoint:xfs:xfs_attr_list_leaf
tracepoint:xfs:xfs_attr_list_leaf_end
[...]
# bpftrace -l | wc -l
46260
```
Other libraries generate probes dynamically, such as uprobe, and require specific ways to determine available probes. See the later [Probes](#probes) sections.
Search terms can be added:
```
# bpftrace -l '*nanosleep*'
tracepoint:syscalls:sys_enter_clock_nanosleep
tracepoint:syscalls:sys_exit_clock_nanosleep
tracepoint:syscalls:sys_enter_nanosleep
tracepoint:syscalls:sys_exit_nanosleep
kprobe:nanosleep_copyout
kprobe:hrtimer_nanosleep
[...]
```
## 5. `-d`: Debug Output
The `-d` option produces debug output, and does not run the program. This is mostly useful for debugging issues with bpftrace itself.
**If you are an end-user of bpftrace, you should not normally need the `-d` or `-v` options, and you can skip to the [Language](#language) section.**
These use uprobes (a Linux kernel capability). `uprobe` instruments the beginning of a user-level function's execution, and `uretprobe` instruments the end (its return).
To list available uprobes, you can use any program to list the text segment symbols from a binary, such as `objdump` and `nm`. For example:
```
# objdump -tT /bin/bash | grep readline
00000000007003f8 g DO .bss 0000000000000004 Base rl_readline_state
0000000000499e00 g DF .text 00000000000001c5 Base readline_internal_char
00000000004993d0 g DF .text 0000000000000126 Base readline_internal_setup
000000000046d400 g DF .text 000000000000004b Base posix_readline_initialize
000000000049a520 g DF .text 0000000000000081 Base readline
[...]
```
This has listed various functions containing "readline" from /bin/bash. These can be instrumented using `uprobe` and `uretprobe`.
Examples:
```
...
...
@@ -258,15 +485,21 @@ Attaching 1 probe...
read a line
read a line
read a line
read a line
^C
```
While tracing, this has caught a few executions of the `readline()` function in /bin/bash. This example is continued in the next section.
Arguments can be accessed via these variables names. arg0 is the first argument.
```
uprobe: arg0, arg1, ..., argN
uretprobe: retval`
```
Arguments can be accessed via these variables names. `arg0` is the first argument, and can only be accessed with a `uprobe`. `retval` is the return value for the instrumented function, and can only be accessed on `uretprobe`.
Examples:
...
...
@@ -279,6 +512,8 @@ arg0: 19755784
^C
```
What does `arg0` of `readline()` in /bin/bash contain? I don't know. I'd need to look at the bash source code to find out what its arguments were.
In this case, I know that the first argument of libc `fopen()` is the pathname (see the fopen(3) man page), so I've traced it using a uprobe. Adjust the path to libc to match your system (it may not be libc-2.23.so). A `str()` call is necessary to turn the char * pointer to a string, as explained in a later section.
Back to the bash `readline()` example: after checking the source code, I saw that the return value was the string read. So I can use a `uretprobe` and the `retval` variable to see the read string.