This shows you the differences between two versions of the page.
|
ep:labs:05:contents:tasks:ex3 [2026/03/31 01:26] radu.mantu |
ep:labs:05:contents:tasks:ex3 [2026/03/31 02:50] (current) radu.mantu |
||
|---|---|---|---|
| Line 71: | Line 71: | ||
| * A [[https://bpftrace.org/docs/release_025/language#filterspredicates|predicate]] specified between the probe name and the action block. | * A [[https://bpftrace.org/docs/release_025/language#filterspredicates|predicate]] specified between the probe name and the action block. | ||
| </note> | </note> | ||
| + | |||
| + | <solution -hidden> | ||
| + | <code bash> | ||
| + | $ sudo bpftrace -e 'tracepoint:syscalls:sys_exit_read /args.ret < 0/ { printf("%s (%d): %d\n", comm, pid, args.ret) }' | ||
| + | kitty (8441): -11 | ||
| + | kitty (8441): -11 | ||
| + | libinput-connec (1357): -11 | ||
| + | |||
| + | $ errno 11 | ||
| + | EAGAIN 11 Resource temporarily unavailable | ||
| + | </code> | ||
| + | </solution> | ||
| === [10p] Task D - Count read bytes === | === [10p] Task D - Count read bytes === | ||
| Line 83: | Line 95: | ||
| Make sure you filter out negative return values and execute your **bpftrace** script. Let it run for a few seconds, then interrupt it via a SIGINT (i.e., //Ctrl + C//). When unloading the probes and before terminating the process, all maps will be printed to //stdout//. | Make sure you filter out negative return values and execute your **bpftrace** script. Let it run for a few seconds, then interrupt it via a SIGINT (i.e., //Ctrl + C//). When unloading the probes and before terminating the process, all maps will be printed to //stdout//. | ||
| + | |||
| + | <solution -hidden> | ||
| + | <code bash> | ||
| + | $ sudo bpftrace -e 'tracepoint:syscalls:sys_exit_read /args.ret > 0/ { @read_bytes[comm] += args.ret }' | ||
| + | </code> | ||
| + | </solution> | ||
| == Periodic statistics == | == Periodic statistics == | ||
| Line 89: | Line 107: | ||
| Use the [[https://bpftrace.org/docs/release_025/language#interval|interval]] probe to achieve this. You can ''print()'' the map and then ''clear()'' it to reset its contents. | Use the [[https://bpftrace.org/docs/release_025/language#interval|interval]] probe to achieve this. You can ''print()'' the map and then ''clear()'' it to reset its contents. | ||
| + | |||
| + | <solution -hidden> | ||
| + | <code bash> | ||
| + | $ sudo bpftrace -e 'tracepoint:syscalls:sys_exit_read /args.ret > 0/ { @read_bytes[comm] += args.ret } interval:s:2 { print(@read_bytes); printf("\n"); clear(@read_bytes) }' | ||
| + | </code> | ||
| + | </solution> | ||
| === [5p] Task E - Built-in histogram function === | === [5p] Task E - Built-in histogram function === | ||
| Use the [[https://bpftrace.org/docs/release_025/stdlib#hist|hist()]] eBPF helper to visualize the distribution of bytes read for each syscall. The data that you visualize is not the total bytes read, but how many **read()** calls returned a value that fits within that specific log2 bucket. | Use the [[https://bpftrace.org/docs/release_025/stdlib#hist|hist()]] eBPF helper to visualize the distribution of bytes read for each syscall. The data that you visualize is not the total bytes read, but how many **read()** calls returned a value that fits within that specific log2 bucket. | ||
| + | |||
| + | <solution -hidden> | ||
| + | <code bash> | ||
| + | $ sudo bpftrace -e 'tracepoint:syscalls:sys_exit_read { @ = hist(args.ret) }' | ||
| + | @: | ||
| + | (..., 0) 303 |@@ | | ||
| + | [0] 531 |@@@@ | | ||
| + | [1] 6246 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@| | ||
| + | [2, 4) 10 | | | ||
| + | [4, 8) 44 | | | ||
| + | [8, 16) 725 |@@@@@@ | | ||
| + | [16, 32) 22 | | | ||
| + | [32, 64) 401 |@@@ | | ||
| + | [64, 128) 32 | | | ||
| + | [128, 256) 55 | | | ||
| + | [256, 512) 85 | | | ||
| + | [512, 1K) 347 |@@ | | ||
| + | [1K, 2K) 104 | | | ||
| + | [2K, 4K) 279 |@@ | | ||
| + | [4K, 8K) 38 | | | ||
| + | [8K, 16K) 15 | | | ||
| + | [16K, 32K) 10 | | | ||
| + | [32K, 64K) 1 | | | ||
| + | </code> | ||
| + | </solution> | ||