手机数据线东莞网站建设,品牌建设工作的意义,网站建设哪个公司比较好,开发前端后端目录 1 bpftrace常用命令1.1 列出bpftrace 相关命令的list1. 2bpftrace -e 是执行1.3 查看参数 -lv 2 bpftrace 可以用到的变量3 高级3.1 内置函数3.2 文件系统3.3 内核内存 栈3.4 Malloc 调用 统计3.5 系统调用 brk 的 统计3.6 脚本调用 4 应用5 怎么串联起来呢 bpftrace 总的… 目录 1 bpftrace常用命令1.1 列出bpftrace 相关命令的list1. 2bpftrace -e 是执行1.3 查看参数 -lv 2 bpftrace 可以用到的变量3 高级3.1 内置函数3.2 文件系统3.3 内核内存 栈3.4 Malloc 调用 统计3.5 系统调用 brk 的 统计3.6 脚本调用 4 应用5 怎么串联起来呢 bpftrace 总的来说是对线上项目的系统调用的函数的观测因为这时已经不能往函数里面加log了。 相关的开源项目 https://github.com/iovisor/bpftrace
1 bpftrace常用命令
1.1 列出bpftrace 相关命令的list
bpftrace -l
$ sudo bpftrace -l | grep accept
tracepoint:syscalls:sys_enter_accept4
tracepoint:syscalls:sys_exit_accept4
tracepoint:syscalls:sys_enter_accept
tracepoint:syscalls:sys_exit_accept
kprobe:bpf_lsm_socket_accept
kprobe:vfs_dentry_acceptable
kprobe:find_acceptable_alias
kprobe:security_socket_accept
kprobe:selinux_socket_accept
kprobe:apparmor_socket_accept1. 2bpftrace -e 是执行
使用命令
# bpftrace -e BEGIN { printf(hello n); }
# bpftrace -e tracepoint:syscalls:sys_enter_accept { printf(accept\n); }
# bpftrace -e tracepoint:syscalls:sys_enter_accept4 { printf(accept4\n); }
# bpftrace -e tracepoint:syscalls:sys_enter_connect { printf(connect\n); }
# bpftrace -e tracepoint:syscalls:sys_enter_read { printf(read\n); }
# bpftrace -e tracepoint:syscalls:sys_enter_write { printf(write\n); }
# bpftrace -e tracepoint:syscalls:sys_enter_close { printf(close\n); }1.3 查看参数 -lv
$ sudo bpftrace -lv tracepoint:syscalls:sys_enter_write
tracepoint:syscalls:sys_enter_writeint __syscall_nr;unsigned int fd;const char * buf;size_t count;bpftrace语法结构 bpftrace的语法结构是参考awk的。 probes /filter/ { action } probes 事件tracepoint, kprobe, kretprobe, uprobe。两个特殊事件 BEGIN/END用于脚本开始和结束处执行 filter 过滤条件事件触发时判断条件例如/pid 3245/表示pid为3245的进程执行。 action 具体执行的操作例如{ printf(“close\n”);} 打印close 想到的应用如上图中kprobe的时候记录一下时间t1kretprobe记录一下时间t2t2-t1就是这个内核函数调用的时间
2 bpftrace 可以用到的变量
内置变量 bpftrace脚本常用变量如下 uid:用户id。 tid线程id pid进程id。 cpucpu id。 cgroupcgroup id. probe当前的trace点。 comm进程名字。 nsecs纳秒级别的时间戳。 kstack内核栈描述 curtask当前进程的task_struct地址。 args:获取该kprobe或者tracepoint的参数列表 arg0:获取该kprobe的第一个变量tracepoint不可用 arg1:获取该kprobe的第二个变量tracepoint不可用 arg2:获取该kprobe的第三个变量tracepoint不可用 retval: kretprobe中获取函数返回值 args-ret: kretprobe中获取函数返回值 自定义变量 以’ ′ 标志起来定义与引用变量例如 标志起来定义与引用变量例如 ′标志起来定义与引用变量例如idx 0;
3 高级
进一步还有 “自定义变量””map变量““内置函数” “文件系统” “磁盘” “进程”。
3.1 内置函数
可以查一下bpftrace的内置函数有哪些 应用举例具体的路径加程序名:函数名 #bpftrace -e ‘tracepoint:syscalls:sys_enter_accept4 { printf(“accept 4 %ld n”, pid); }’
3.2 文件系统
统计调用read 的次数 #bpftrace e t:syscalls:sys_enter_read {[probe]count();
3.3 内核内存 栈
#bpf trace e t:kmem:kmem_cache_alloc { bytes[kstack] sum(args --bytes_alloc);
分析内核实时函数栈, 统计ip_output 调用栈: #bpftrace -e ‘kprobe:ip_output { [kstack()] count(); } interval:s:10 { exit(); }’ #bpftrace -e ‘kprobe:ip_output { [kstack(3)] count(); }’
3.4 Malloc 调用 统计
#bpftrace e u:/lib/x86_64 linux gnu/libc.so.6:malloc {[ustack, comm] sum(arg0);
3.5 系统调用 brk 的 统计
#统计 统计进程进程发生发生缺页缺页中断中断 #bpftrace bpftrace --e ‘t:exceptions:page_fault_user { [ustack, comm] e ‘t:exceptions:page_fault_user { [ustack, comm] count(); }’ count(); }’
3.6 脚本调用
比如侦测系统调用 accept查IP端口… inet_csk_accept 这个函数是通过 bpftrace -l grep相关的accept函数然后结合内核源码找到的 $ sudo bpftrace -l | grep inet_csk_accept kprobe:inet_csk_accept
eg1 : 新建一个accept.bt的文件内容如下(这里需要查阅一下bpftrace的语法与应用举例了)
#include net/sock.hBEGIN
{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; // retval是inet_csk_accept的返回值$raddr ntop($sk-__sk_common.skc_daddr); // ntop 是将32位的值转换IP地址加port模式,类似 地址转换函数inet_ntoa、inet_ntop、inet_pton、inet_addr // ntop([int af, ]int|char[4|16] addr) Convert IP address data to text$laddr ntop($sk-__sk_common.skc_rcv_saddr);time(%H:%M:%S);printf(%6d %15s, pid, comm);printf(%20s, %20s\n, $raddr, $laddr);}执行#bpftrace accept.bt 参考 eg2: accept4.bt 里面探测write方法可以打印出buf可以包括很多信息比如用户名密码因此这些信息要用密文至少不那么容易破解。
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 \n);
}tracepoint:syscalls:sys_enter_read
/ comm nginx/
{printf( read %s, %d\n, comm, pid);
}tracepoint:syscalls:sys_enter_write
/ comm git || comm git-remote-http/
{printf( write %s, %d, buf: %s\n, comm, pid, str(args-buf));
}执行 #bpftrace accept4.bt
4 应用
类似 tcpdump -i eth0
5 怎么串联起来呢
就是要对内核比较熟悉对文件操作vfs…网络操作熟悉然后灵活运用。 eg3 vfs的例子
#include linux/fs.h
#include linux/path.h
#include linux/dcache.hkprobe: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 file*)arg0)-f_path.dentry-d_name.name);printf(vfs_write: %s, count: %d, buf:%s\n, $file, arg2, str(arg1));
}可以用cat命令去测试cat一个文件可以触发vfs_open。参考