首页 > 其他分享 >ebpf-4——reference_guide.md翻译与实验

ebpf-4——reference_guide.md翻译与实验

时间:2022-11-22 18:13:03浏览次数:44  
标签:md probe reference bpftrace ebpf i64 kprobe ... printf

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

相关文章

  • 解决MDL锁导致无法操作数据库的问题
    背景信息MySQL5.5版本开始,引入了MDL锁,用于解决或者保证DDL操作与DML操作之间的一致性,但是在部分场景下会出现阻塞,例如执行DML操作时执行ALTER操作、存在长时间查询时执行......
  • 发现cmdbcs.exe,upxdnd.exe,SSLDyn.exe…爱莫能助
    发现cmdbcs.exe,upxdnd.exe,SSLDyn.exe…爱莫能助——值得讨论的安全观endurer原创2007-12-26第1版 刚才一位网友说她电脑中的瑞星实时监控小伞不见了,瑞星杀......
  • ebpf-2——Android中的eBPF程序
    一、简介1.Android从9.0版本开始全面支持eBPF,其主要用在流量统计上。此外,eBPF可以与内核的kprobe/tracepoints/skfilter等模块相结合,hook内核事件从而监控相应的系统......
  • ebpf-1——ebpf初探
    一、简介1.eBPF提供可基于系统或程序事件高效安全执行一段特定代码的通用能力,涵盖了性能分析、系统追踪、网络优化等方面。2.eBPF有以下优势强安全:BPF验证器(verif......
  • MDFEND: Multi-domain Fake News Detection
    MDFEND:Multi-domainFakeNewsDetectionMDFEND:多领域假新闻检测作者:南琼、曹娟  CIKM2021shortpaper论文地址:https://arxiv.org/pdf/2201.00987.pdf数据集和......
  • Windows平台在当前文件夹下打开CMD
    Windows平台在当前文件夹下打开CMD的方法:在路径栏中输入 cmd.exe ,然后敲回车。 ......
  • mmdetection:在定制数据集上训练检测器
     要训练新的检测器,通常需要做三件事:1.验证新数据集2.修改配置3.训练新的检测器有三种方法supportMMDetection中的新数据集:1. Reorganizethe......
  • Windows卸载Anaconda导致CMD以错误码1退出
    起因今天打开之前的前端项目,用npm命令启动发现npm命令没有任何输出,每次输完直接换行,没有任何输出起初以为是npm出了问题,重启电脑,重装了node发现没有用然......
  • Windows鼠标右键添加cmd终端,作者已死
    程序员或者非程序员,在某些场景下,需要使用到cmd终端,大多数人使用cmd终端都是win+r输入cmd敲回车,或者在左下角搜索框输入cmd回车(鼠标右击管理员方式运行cmd),还有一种通过查找......
  • MD5,SHA1,SHA256等 哈希散列工具类
    MD5,SHA1,SHA256等哈希散列工具类packagecom.wbc.utils;importjava.security.MessageDigest;importjava.security.NoSuchAlgorithmException;/***MD5,SHA1,SH......