https://github.com/iovisor/bpftrace/blob/master/docs/reference_guide.md
一、说明
bpftrace 参考指南
有关参考摘要,请参阅 README.md 中有关探测器类型的部分以及本指南中的探测器、变量内置和函数内置部分。
这是一个进展中的工作。 如果缺少某些内容,请检查 bpftrace 源码以查看这些文档是否已过时。 如果您发现了什么,请提交问题或拉
取请求以更新这些文档。 此外,请使这些文档尽可能简洁以保持简洁(灵感来自 v7vol2b.pdf 第 106 页的 6 页 awk 摘要)。 将更长
的示例和讨论留给 /docs 中的其他文件、/tools/*_examples.txt 文件或博客文章和其他文章。
二、Terminology
术语 说明 -------------------------------------- BPF Berkeley Packet Filter:一种内核技术,最初是为优化数据包过滤器的处理而开发的(例如,tcpdump 表达式) eBPF Enhanced BPF:一种扩展 BPF 的内核技术,使其可以对任何事件执行更通用的程序,例如下面列出的 bpftrace 程序。 它利用 BPF 沙盒虚拟机环境。 另请注意,eBPF 通常简称为 BPF。 probe 软件或硬件中的检测点,它生成可以执行 bpftrace 程序的事件。 static tracing 代码中的硬编码检测点。 由于这些是固定的,因此它们可以作为稳定 API 的一部分提供并记录在案。 dynamic tracing 也称为动态检测,这是一种可以通过实时修改指令文本来检测任何软件事件(例如函数调用和返回)的技术。 目标软件通常不需要特殊功能来支持动态跟踪,除了 bpftrace 可以读取的符号表。 由于这会检测所有软件文本, 因此它不被认为是稳定的 API,并且目标函数可能不会在其源代码之外记录。 tracepoints 一种用于提供静态跟踪的 Linux 内核技术。 kprobes 一种 Linux 内核技术,用于提供内核功能的动态跟踪。 uprobes 一种 Linux 内核技术,用于提供用户级函数的动态跟踪。 USDT User Statically-Defined Tracing:用户级软件的静态追踪点。 一些应用程序支持 USDT。 BPF map 一个 BPF 内存对象,bpftrace 使用它来创建许多更高级别的对象。 BTF BPF Type Format:编码与 BPF 程序/映射相关的调试信息的元数据格式。
三、Usage
不带选项的 bpftrace 总结了命令行用法:
# bpftrace USAGE: bpftrace [options] filename bpftrace [options] -e 'program' OPTIONS: -B MODE output buffering mode ('line', 'full', or 'none') -d debug info dry run -dd verbose debug info dry run -e 'program' execute this program -h show this help message -I DIR add the specified DIR to the search path for include files. --include FILE adds an implicit #include which is read before the source file is preprocessed. -l [search] list probes -p PID enable USDT probes on PID -c 'CMD' run CMD and enable USDT probes on resulting process //bpftrace和要trace的命令写在同一行 ######### -q keep messages quiet -v verbose messages -k emit a warning when a bpf helper returns an error (except read functions) -kk check all bpf helper functions --version bpftrace version ENVIRONMENT: BPFTRACE_STRLEN [default: 64] bytes on BPF stack per str() BPFTRACE_NO_CPP_DEMANGLE [default: 0] disable C++ symbol demangling BPFTRACE_MAP_KEYS_MAX [default: 4096] max keys in a map BPFTRACE_MAX_PROBES [default: 512] max number of probes bpftrace can attach to BPFTRACE_MAX_BPF_PROGS [default: 512] max number of generated BPF programs BPFTRACE_CACHE_USER_SYMBOLS [default: auto] enable user symbol cache BPFTRACE_VMLINUX [default: none] vmlinux path used for kernel symbol resolution BPFTRACE_BTF [default: none] BTF file EXAMPLES: bpftrace -l '*sleep*' list probes containing "sleep" //Segmentation fault bpftrace -e 'kprobe:do_nanosleep { printf("PID %d sleeping...\n", pid); }' trace processes calling sleep bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }' count syscalls by process name
1. Hello World
bpftrace 程序的最基本示例:
# bpftrace -e 'BEGIN { printf("Hello, World!\n"); }' Attaching 1 probe... Hello, World! ^C
该程序的语法将在 Language 部分进行解释。 在本节中,我们将介绍工具的使用。
程序将继续运行,直到按下 Ctrl-C 或调用 exit() 函数。 当程序退出时,将打印所有填充的maps:此行为和maps将在后面的部分中解释。
2. -e 'program': One-Liners
-e 选项允许指定一个程序,并且是一种构造单行代码的方法:
# 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. [...]
此示例在进程调用 nanosleep 系统调用时打印。 同样,程序的语法将在 Language 部分进行解释。
3. filename: Program Files
保存为文件的程序通常称为脚本,可以通过指定文件名来执行。 我们通常会使用 .bt 文件扩展名,它是 bpftrace 的缩写,但该扩展名会被忽略。
例如,使用 cat -n(枚举输出行)列出 sleepers.bt 文件:
# cat -n sleepers.bt 1 tracepoint:syscalls:sys_enter_nanosleep 2 { 3 printf("%s is sleeping.\n", comm); 4 }
运行 sleepers.bt:
# bpftrace sleepers.bt Attaching 1 probe... iscsid is sleeping. iscsid is sleeping. [...]
它还可以使其可执行文件独立运行。 首先在顶部添加一个解释器行 (#!),其中包含安装的 bpftrace 的路径(/usr/local/bin 是默认值)或 env 的路径(通常只是 /usr/bin/env),然后是 bpftrace (所以它会在你的 $PATH 中找到 bpftrace):
1 #!/usr/local/bin/bpftrace 2 3 tracepoint:syscalls:sys_enter_nanosleep 4 { 5 printf("%s is sleeping.\n", comm); 6 }
然后使其可执行:
# chmod 755 sleepers.bt # ./sleepers.bt Attaching 1 probe... iscsid is sleeping. iscsid is sleeping. [...]
4. -l: Listing Probes
来自 tracepoint 和 kprobe 库的探测可以用 -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
其他库动态生成探针,例如 uprobe,并且需要特定的方法来确定可用的探针。 请参阅后面的 Probes 部分。
可以添加搜索词:
# 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 [...]
列出跟踪点时的 -v 选项将显示它们的参数以供 args 内置函数使用。 例如:
# bpftrace -lv tracepoint:syscalls:sys_enter_open tracepoint:syscalls:sys_enter_open int __syscall_nr; const char * filename; int flags; umode_t mode;
如果 BTF 可用,也可以列出 struct/union/enum 定义。 例如:
# bpftrace -lv "struct path" struct path { struct vfsmount *mnt; struct dentry *dentry; };
5. -d: Debug Output
-d 选项产生调试输出,但不运行程序。 这主要用于调试 bpftrace 本身的问题。 您还可以使用 -dd 生成更详细的调试输出,这也将打印未优化的 IR。
如果您是 bpftrace 的最终用户,您通常不需要 -d 或 -v 选项,您可以跳到 Language 部分。
# bpftrace -d -e 'tracepoint:syscalls:sys_enter_nanosleep { printf("%s is sleeping.\n", comm); }' Program tracepoint:syscalls:sys_enter_nanosleep call: printf string: %s is sleeping.\n builtin: comm [...]
输出以 Program 开头,然后是程序的抽象语法树 (AST) 表示。
继续:
[...] %printf_t = type { i64, [16 x i8] } [...] define i64 @"tracepoint:syscalls:sys_enter_nanosleep"(i8*) local_unnamed_addr section "s_tracepoint:syscalls:sys_enter_nanosleep" { entry: %comm = alloca [16 x i8], align 1 %printf_args = alloca %printf_t, align 8 %1 = bitcast %printf_t* %printf_args to i8* call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %1) %2 = getelementptr inbounds [16 x i8], [16 x i8]* %comm, i64 0, i64 0 %3 = bitcast %printf_t* %printf_args to i8* call void @llvm.memset.p0i8.i64(i8* nonnull %3, i8 0, i64 24, i32 8, i1 false) call void @llvm.lifetime.start.p0i8(i64 -1, i8* nonnull %2) call void @llvm.memset.p0i8.i64(i8* nonnull %2, i8 0, i64 16, i32 1, i1 false) %get_comm = call i64 inttoptr (i64 16 to i64 (i8*, i64)*)([16 x i8]* nonnull %comm, i64 16) %4 = getelementptr inbounds %printf_t, %printf_t* %printf_args, i64 0, i32 1, i64 0 call void @llvm.memcpy.p0i8.p0i8.i64(i8* nonnull %4, i8* nonnull %2, i64 16, i32 1, i1 false) %pseudo = call i64 @llvm.bpf.pseudo(i64 1, i64 1) %get_cpu_id = call i64 inttoptr (i64 8 to i64 ()*)() %perf_event_output = call i64 inttoptr (i64 25 to i64 (i8*, i8*, i64, i8*, i64)*)(i8* %0, i64 %pseudo, i64 %get_cpu_id, %printf_t* nonnull %printf_args, i64 24) call void @llvm.lifetime.end.p0i8(i64 -1, i8* nonnull %1) ret i64 0 [...]
本节展示 llvm 中间表示 (IR) 程序集,然后将其编译到 BPF 中。
6. -v: Verbose Output
-v 选项在程序运行时打印有关该程序的更多信息:
# bpftrace -v -e 'tracepoint:syscalls:sys_enter_nanosleep { printf("%s is sleeping.\n", comm); }' Attaching 1 probe... The verifier log: 0: (bf) r6 = r1 1: (b7) r1 = 0 2: (7b) *(u64 *)(r10 -24) = r1 ... 23: (b7) r5 = 24 24: (85) call bpf_perf_event_output#25 25: (b7) r0 = 0 26: (95) exit processed 26 insns (limit 131072), stack depth 40 Attaching tracepoint:syscalls:sys_enter_nanosleep iscsid is sleeping. iscsid is sleeping. [...]
这包括验证器(verifier )日志:然后是来自内核验证器的日志消息。
增加一个Android上的demo,可以打印出id:
# bpftrace -v -e 'kprobe:do_nanosleep { printf("PID %d sleeping...\n", pid); }' INFO: node count: 7 Attaching 1 probe... Program ID: 44 The verifier log: processed 15 insns (limit 1000000) max_states_per_insn 0 total_states 1 peak_states 1 mark_read 0 Attaching kprobe:do_nanosleep PID 1 sleeping... PID 1616 sleeping... PID 2622 sleeping...
7. Preprocessor Options
-I 选项可用于将目录添加到 bpftrace 查找标头文件的目录列表中。 可以定义多次。
# cat program.bt #include <foo.h> BEGIN { @ = FOO } # bpftrace program.bt definitions.h:1:10: fatal error: 'foo.h' file not found # ls /tmp/include foo.h # bpftrace -I /tmp/include program.bt Attaching 1 probe...
--include 选项可用于包含头文件。 可以定义多次。 头文件按照它们定义的顺序包含,并且它们在正在执行的程序中的任何其他包含之前被包含。
# bpftrace --include linux/path.h --include linux/dcache.h \ -e 'kprobe:vfs_open { printf("open path: %s\n", str(((struct path *)arg0)->dentry->d_name.name)); }' Attaching 1 probe... open path: .com.google.Chrome.ASsbu2 open path: .com.google.Chrome.gimc10 open path: .com.google.Chrome.R1234s
8. Other Options
--version 选项打印 bpftrace 版本。 --no-warnings 选项禁用警告。
# bpftrace --version bpftrace v0.8-90-g585e-dirty
9. Environment Variables
9.1 BPFTRACE_STRLEN
默认值:64,为 str() 返回的字符串在 BPF 堆栈上分配的字节数。如果您希望使用 str() 读取更大的字符串,请将其设置得更大。
请注意 BPF 堆栈很小(512 字节),并且您在 printf() 中再次使用(同时它组成了一个 perf 事件输出缓冲区)。 所以在实践中你只能将它增加到大约 200 字节。
正在讨论支持更大的字符串。
9.3 BPFTRACE_MAP_KEYS_MAX
默认值:4096,这是可以存储在映射中的最大键数。 增加该值将消耗更多内存并增加启动时间。 在某些情况下您会想要:例如,采样堆栈跟踪、记录每个页面的时间戳等。
9.4 BPFTRACE_MAX_PROBES
默认值:512,这是 bpftrace 可以附加的最大探测数。 增加该值将消耗更多内存,增加启动时间并可能导致高性能开销甚至冻结或崩溃系统。
9.5 BPFTRACE_CACHE_USER_SYMBOLS
默认值:如果在系统上启用了 ASLR 且未给出 -c 选项,则为 0; 否则为 1。
默认情况下,bpftrace 仅在禁用 ASLR(地址空间布局随机化)时才缓存符号解析结果。 这是因为每次使用 ASLR 执行时,符号地址都会发生变化。 但是,禁用缓存可能会降低性能。 将此环境变量设置为 1 以强制 bpftrace 进行缓存。 如果只跟踪一个程序的执行,这很好。
9.6 BPFTRACE_VMLINUX
默认值:None,这指定了将 kprobe 附加到偏移量时用于内核符号解析的 vmlinux 路径。 如果未给出此值,bpftrace 会从预定义的位置搜索 vmlinux。 有关详细信息,请参阅 src/attached_probe.cpp:find_vmlinux()。
9.7 BPFTRACE_BTF
默认值:None,BTF 文件的路径。 默认情况下,bpftrace 会搜索多个位置来查找 BTF 文件。 有关详细信息,请参阅 src/btf.cpp。
9.8 BPFTRACE_PERF_RB_PAGES
默认值:64,每个 CPU 为 perf 环形缓冲区分配的页数。 该值必须是 2 的幂。
bpftrace 可能无法足够快地处理环形缓冲区中的事件,这可能导致丢弃大量事件。 提高该值可能很有用,这样可以让更多事件排队。 代价是 bpftrace 将使用更多内存。
9.9 BPFTRACE_MAX_BPF_PROGS
默认值:512,这是 bpftrace 可以生成的 BPF 程序(函数)的最大数量。 此限制的主要目的是防止 bpftrace 挂死,因为生成大量探测会占用大量资源(不应经常发生)。
10. Clang Environment Variables
bpftrace 使用 libclang(Clang 的 C 接口)解析头文件。 因此环境变量可以影响被使用的 clang 工具链。 例如,如果从非默认目录包含头文件,则可以设置 CPATH 或 C_INCLUDE_PATH 环境变量以允许 clang 定位文件。 有关这些环境变量及其用法的更多信息,请参阅clang 文档。
四、Language
1. {...}: Action Blocks
语法:probe[,probe,...] /filter/ { action }
一个 bpftrace 程序可以有多个操作块。 过滤器是可选的。
例子:
# bpftrace -e 'kprobe:do_sys_open { printf("opening: %s\n", str(arg1)); }' Attaching 1 probe... opening: /proc/cpuinfo opening: /proc/stat opening: /proc/diskstats opening: /proc/stat opening: /proc/vmstat [...]
这是 bpftrace 的单行调用。 探测是 kprobe:do_sys_open。 当该探测器“触发”(检测事件发生)时,将执行由 print() 语句组成的操
作。 探测器和操作的说明在以下部分中。
2. /.../: Filtering
语法:/filter/
可以在探测器名称后添加过滤器(也称为谓词)。 探测器仍会触发,但它将跳过操作,除非过滤器为真。
例子:
# bpftrace -e 'kprobe:vfs_read /arg2 < 16/ { printf("small read: %d byte buffer\n", arg2); }' Attaching 1 probe... small read: 8 byte buffer small read: 12 byte buffer ^C # bpftrace -e 'kprobe:vfs_read /comm == "bash"/ { printf("read by %s\n", comm); }' Attaching 1 probe... read by bash ^C
3. //, /*: Comments
语法:
// single-line comment /* * multi-line comment */
这些可以在 bpftrace 脚本中用于注释您的代码。
4. Literals
支持整数、字符和字符串文字。 整数字面值是一个数字序列,带有可选的下划线 (_) 作为字段分隔符。 也支持科学记数法,但仅适用于整数值,因为 BPF 不支持浮点数。
# bpftrace -e 'BEGIN { printf("%lu %lu %lu", 1000000, 1e6, 1_000_000)}' Attaching 1 probe... ^C 1000000 1000000 1000000
字符文字用单引号括起来,例如 'a' 和 '@'。字符串文字用双引号括起来,例如 “一个字符串”。
5. ->: C Struct Navigation
tracepoint 例子:
# bpftrace -e 'tracepoint:syscalls:sys_enter_openat { printf("%s %s\n", comm, str(args->filename)); }' Attaching 1 probe... snmpd /proc/diskstats snmpd /proc/stat snmpd /proc/vmstat [...]
这是从 args 结构返回文件名成员,对于跟踪点探测器,它包含跟踪点参数。 有关此结构的内容,请参阅Static Tracing, Kernel-Level Arguments 部分。
kprobe 示例:
# cat path.bt #include <linux/path.h> #include <linux/dcache.h> kprobe:vfs_open { printf("open path: %s\n", str(((struct path *)arg0)->dentry->d_name.name)); } # bpftrace path.bt Attaching 1 probe... open path: dev open path: if_inet6 open path: retrans_time_ms [...]
这通过短脚本 path.bt 使用 vfs_open() 内核函数的动态跟踪。 需要包含一些内核头文件以理解 path 和 dentry 的结构。
6. struct: Struct Declaration
例子:
// from fs/namei.c: struct nameidata { struct path path; struct qstr last; // [...] };
您可以在需要时定义自己的结构。 在某些情况下,内核结构未在内核头文件包中声明,而是在 bpftrace 工具中手动声明(或部分结构:但需要足够解引用成员变量)。
7. ? :: ternary operators
例子:
# bpftrace -e 'tracepoint:syscalls:sys_exit_read { @error[args->ret < 0 ? - args->ret : 0] = count(); }' Attaching 1 probe... ^C @error[11]: 24 @error[0]: 78 # bpftrace -e 'BEGIN { pid & 1 ? printf("Odd\n") : printf("Even\n"); exit(); }' Attaching 1 probe... Odd
8. if () {...} else {...}: if-else statements
例子:
# bpftrace -e 'tracepoint:syscalls:sys_enter_read { @reads = count(); if (args->count > 1024) { @large = count(); } }' Attaching 1 probe... ^C @large: 72 @reads: 80
9. unroll () {...}: unroll
例子:
# bpftrace -e 'kprobe:do_nanosleep { $i = 1; unroll(5) { printf("i: %d\n", $i); $i = $i + 1; } }' Attaching 1 probe... i: 1 i: 2 i: 3 i: 4 i: 5 ^C
10. ++ and --: increment operators
++ 和 -- 可用于方便地递增或递减映射或变量中的计数器。请注意,如果尚未声明或定义,映射将被隐式声明并初始化为 0。 临时变量必须在使用这些运算符之前进行初始化。
示例 - 变量:
# bpftrace -e 'BEGIN { $x = 0; $x++; $x++; printf("x: %d\n", $x); }' Attaching 1 probe... x: 2 ^C
示例 - map:
bpftrace -e 'k:vfs_read { @++ }' Attaching 1 probe... ^C @: 12807
示例 - 带有key的map:
# bpftrace -e 'k:vfs_read { @[probe]++ }' Attaching 1 probe... ^C @[kprobe:vfs_read]: 13369
11. []: Array access
您可以使用数组访问运算符 [] 访问一维常量数组。
例子:
# bpftrace -e 'struct MyStruct { int y[4]; } uprobe:./testprogs/array_access:test_struct { $s = (struct MyStruct *) arg0; @x = $s->y[0]; exit(); }' Attaching 1 probe... @x: 1
测试代码:
struct my_struct { int a[4]; }; static __attribute__((__noinline__)) void test_struct(struct my_struct *p) { p->a[0]++; p->a[1]++; p->a[2]++; p->a[3]++; } void main() { struct my_struct ms = {1, 2, 3, 4}; test_struct(&ms); }
12. Integer casts
整数在内部表示为 64 位有符号数。 如果您需要其他表示,您可以转换为以下内置类型:
Type Explanation ------------------------------ uint8 unsigned 8 bit integer int8 signed 8 bit integer uint16 unsigned 16 bit integer int16 signed 16 bit integer uint32 unsigned 32 bit integer int32 signed 32 bit integer uint64 unsigned 64 bit integer int64 signed 64 bit integer
示例:
# bpftrace -e 'BEGIN { $x = 1<<16; printf("%d %d\n", (uint16)$x, $x); }' Attaching 1 probe... 0 65536 ^C
13. Looping constructs
实验性的,内核:5.3,bpftrace 支持 C 风格的 while 循环:
# bpftrace -e 'i:ms:100 { $i = 0; while ($i <= 100) { printf("%d ", $i); $i++} exit(); }'
可以使用 continue 和 break 关键字来缩短循环。
14. return: Terminate Early
return 关键字用于退出当前探测。 这与 exit() 的不同之处在于它不会退出 bpftrace。
自己添加的示例:
# if 语句中即使只有一条语句,也必须要有大括号 bpftrace -e 'i:ms:100 { $i = 0; while ($i <= 100) { printf("%d ", $i); if ($i == 50) { $i++; } $i++} exit(); }' # 死循环了,每次都加到50 bpftrace -e 'i:ms:100 { $i = 0; while ($i <= 100) { printf("%d ", $i); if ($i == 50) { return; } $i++} exit(); }' # 加到50就退出了 bpftrace -e 'i:ms:100 { $i = 0; while ($i <= 100) { printf("%d ", $i); if ($i == 50) { exit(); } $i++} exit(); }'
15. ( , ): Tuples
支持 N 元组,其中 N 是大于 1 的任何整数。索引支持使用 . 操作符。 元组一旦创建就不可变。
例子:
# bpftrace -e 'BEGIN { $t = (1, 2, "string"); printf("%d %s\n", $t.1, $t.2); }' Attaching 1 probe... 2 string ^C
五、Probes
kprobe - 内核函数开始 kretprobe - 内核函数返回 uprobe - 用户空间函数开始 uretprobe - 用户空间函数返回 tracepoint - 内核静态跟踪点 usdt - 用户空间静态跟踪点 profile - 定时采样 interval - 定时输出 software - 内核软件事件 hardware - 处理器级事件
一些探测类型允许通配符匹配多个探测,例如,kprobe:vfs_*。 您还可以使用逗号分隔列表为操作块指定多个附加点。
带引号的字符串(例如 uprobe:"/usr/lib/c++lib.so":foo)可用于转义附加点定义中的字符。
1. kprobe/kretprobe: Dynamic Tracing, Kernel-Level
语法:
kprobe:function_name[+offset] kretprobe:function_name
这些使用 kprobes(Linux 内核功能)。 kprobe 检测函数执行的开始,kretprobe 检测结束(它的返回)。
例子:
# bpftrace -e 'kprobe:do_nanosleep { printf("sleep by %d\n", tid); }' Attaching 1 probe... sleep by 1396 sleep by 3669 ^C
也可以在探测函数中指定偏移量:
# gdb -q /usr/lib/debug/boot/vmlinux-`uname -r` --ex 'disassemble do_sys_open' Reading symbols from /usr/lib/debug/boot/vmlinux-5.0.0-32-generic...done. Dump of assembler code for function do_sys_open: 0xffffffff812b2ed0 <+0>: callq 0xffffffff81c01820 <__fentry__> 0xffffffff812b2ed5 <+5>: push %rbp 0xffffffff812b2ed6 <+6>: mov %rsp,%rbp 0xffffffff812b2ed9 <+9>: push %r15 ... # bpftrace -e 'kprobe:do_sys_open+9 { printf("in here\n"); }' Attaching 1 probe... in here ...
如果地址与指令边界对齐并在函数内,则使用 vmlinux(带有调试符号)检查地址。 如果不是,我们将无法添加它:
# bpftrace -e 'kprobe:do_sys_open+1 { printf("in here\n"); }' Attaching 1 probe... Could not add kprobe into middle of instruction: /usr/lib/debug/boot/vmlinux-5.0.0-32-generic:do_sys_open+1
如果 bpftrace 是使用 ALLOW_UNSAFE_PROBE 选项编译的,则可以使用 --unsafe 选项跳过检查。 在这种情况下,linux 内核仍然检查指令对齐。
可以使用环境变量 BPFTRACE_VMLINUX 覆盖默认的 vmlinux 路径。
现场示例:(kprobe) search /tools (kretprobe) /tools,这两个超链接分别为:
https://github.com/iovisor/bpftrace/search?q=kprobe%3A+path%3Atools&type=Code
https://github.com/iovisor/bpftrace/search?q=kretprobe%3A+path%3Atools&type=Code
.bt脚本中可以同时列多个:
kprobe:vfs_read*, kprobe:vfs_write*, kprobe:vfs_fsync,
2. kprobe/kretprobe: Dynamic Tracing, Kernel-Level Arguments
语法:
标签:md,probe,reference,bpftrace,ebpf,i64,kprobe,...,printf From: https://www.cnblogs.com/hellokitty2/p/16915953.html