后端技术_内核bpf的实现原理
最近更新:2024-09-23
|
字数总计:583
|
阅读估时:2分钟
|
阅读量:次
- bpftrace使用
- probes
- bpftrace原理
bpftrace使用
- 单一挂载
1 2 3 4 5 6 7 8 9 10 11 12 13
| bpftrace -e 'uprobe:/usr/local/nginx/sbin/nginx:ngx_close_connection{printf("close connection\n");}'
# # # # #
bpftrace -l "*accept*" # 列出所有包含accept的可挂载点
bpftrace -e "tracepoint:syscalls:sys_enter_accept{printf("accept\n");}" bpftrace -e "tracepoint:syscalls:sys_enter_accept{printf("accept %s\n",comm);}" bpftrace -lv "tracepoint:syscalls:sys_enter_read" # 查看挂载点参数,参数可以用args和arg1...取出
|
- 多挂载
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| tracepoint:syscalls:sys_enter_accept4 { printf("accept4 %s\n", comm); } tracepoint:syscalls:sys_enter_accept { printf("accept %s\n", comm); } tracepoint:syscalls:sys_enter_connect { printf("connect"); } tracepoint:syscalls:sys_enter_read / comm == "ngnix" / { printf(" read %s, %d, buf:%s \n", comm, pid , str(args->buf)); }
|
- bpftrace实现tcpdump
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| ##include <net/sock.h> BEGIN { printf("%8s %6s %15s", "TIME", "PID", "COMM"); printf("%20s %6s %20s %6s\n", "RADDR", "RPORT", "LADDR", "LPORT"); } kretprobe:inet_csk_accept { $sk = (struct sock*)retval; $raddr = ntop($sk->__sk_common.skc_daddr); $laddr = ntop($sk->__sk_common.skc_rcv_saddr); time("%H:%M:%S"); printf("%6d %15s", pid, comm); printf("%20s, %20s\n", $radd, $laddr); }
|
- bpftrace实现文件读写跟踪
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| ##include <linux/fs.h> ##include <linux/path.h> ##include <linux/dcache.h> kprobe:vfs_open / comm == "cat" / { printf("vfs_open: %s, name: %s\n", comm, str(((struct path*)arg0)->dentry->d_name.name)); } kprobe:vfs_write / comm == "cat" / { $file = str(((struct path*)arg0)->f_path.dentry->d_name.name); printf("vfs_write: %s,count: %d, buf:%s\n", $file, arg2, str(arg1)); }
|
- bpftrace跟踪写裸盘
1
| bpftrace -e "kprobe:nvme_submit_io{printf("submit io\n");}"
|
- bpftrace跟踪ext4
1 2 3 4 5 6 7
| ##include <linux/fs.h> ##include <linux/path.h> ##include <linux/dcache.h> kprobe:ext4_file_open { printf("ext4_file_open %s, filename:%s\n", comm, str(((struct path*)arg0)->f_path.dentry->d_name.name)); }
|
- bpftrace跟踪内存泄漏
1 2 3 4 5 6 7 8 9 10 11
| uretprobe:/lib/x86_64-linux-gnu/libc.so.6:malloc / comm == "memleak" / { $ret = retval; printf("malloc : %p \n", $ret); } uretprobe:/lib/x86_64-linux-gnu/libc.so.6:free / comm == "memleak" / { printf("free : %p \n", arg0); }
|
probes
| 缩写 |
类型 |
描述 |
| t |
tracepoint |
内核静态探针 |
| u |
usdt |
用户态静态定义探针 |
| k |
kprobe |
内核态动态函数探针 |
| kr |
kretprobe |
内核态动态函数返回值探针 |
| f |
kfunc |
基于BPF的内核态动态函数探针 |
| fr |
kretfunc |
基于BPF的内核态动态函数返回值探针 |
| u |
uprobe |
用户态函数探针 |
| ur |
uretprobe |
用户态函数返回值探针 |
| s |
software |
内核软件事件 |
| h |
hardware |
基于硬件计数器的探针 |
| w |
watchpoint |
基于内存的检测点事件 |
| p |
profile |
对所有cpu进行时间采样 |
| i |
profile |
对所有cpu进行时间采样 |
|
iter |
遍历跟踪内核对象 |
|
BEGIN |
bpftrace启动执行动作 |
|
END |
bpftrace退出执行动作 |
bpftrace原理
2024-03-17
该篇文章被 Cleofwine
归为分类:
服务端