# 功能说明
提供封装易用的ftrace工具,简化对系统流程中的跟踪
# 1、产生背景
我们可以采用以下手段来trace内核调用,只说缺点:
## 1.1、kprobe/jprobe/kretprobe
- 侵入式插入ko,危险系数高
- 需要编写内核代码,难度系数大
## 1.2、systemtap
- 需要编写stp代码,步骤较多
## 1.3、bpf(含bcc和libebpf)
- 需要高版本内核支持
- 需要编写两处代码,步骤较多
## 1.4、ftrace-kprobe
- 配置步骤繁琐,从配置到看出效果,至少要经历五个以上的步骤
- 功能受限,对知识点要求较高
## 1.5、perf-tools kprobe
后来我发现了greg 写的一个kprobe 封装工具:https://github.com/brendangregg/perf-tools/blob/master/kernel/kprobe,它可以把繁杂的ftrace 一个 kprobe event 缩略为一个命令,极大拓展了我对ftrace的了解。然而这个工具使用起来仍有以下困难:
- 只能追踪一个kprobe点,我往往需要追踪多个kprobe点;
- 深入追踪困难:比如我们要在__netif_receive_skb_core 函数中打出skb参数中ip头里面的protocol成员,对应的表达式是 **proto=+0x9(+0xf0(%di)):s8**,光推导这个表达式的过程或许要耗费我们10分钟左右的时间。而且这个表达式并非固定不变,在不同的内核上还需要重新计算;
上述两点成为了我使用ftrace的拦路虎,一直想对它改造优化,但受限于自己的蹩脚的bash能力,进展比较慢。于是换了一个思路,改用python。
# 2、surftrace 准备工作
## 2.1、命名约定
在后面的使用中,会用到两类表达式,一种是程序员可以直观通过结构体定义理解的,比如:
```bash
p __netif_receive_skb_core proto=@(struct iphdr *)l3%0->protocol ip_src=@(struct iphdr *)l3%0->saddr ip_dst=@(struct iphdr *)l3%0->daddr data=@(struct iphdr *)l3%0->sdata[1] f:proto==1&&ip_src==127.0.0.1
```
称为**结构化表达式**
这类表达式不能被ftrace识别,需要在surftrace中进行转换,转换后的
```bash
p __netif_receive_skb_core proto=+0x9(+0xf0(%di)):x8 ip_src=+0xc(+0xf0(%di)):x32 ip_dst=+0x10(+0xf0(%di)):x32 type=+0x14(+0xf0(%di)):x8 seq=+0x1c(+0xf0(%di)):s16 f:common_pid==0&&proto==1&&ip_src==0x100007f
```
称为**ftrace表达式**
# 2.2、依赖条件
如果你想使用surftrace的完整功能,至少需要以下条件:
- 内核支持ftrace、已经mount了debugfs、root权限
- python2.7或更高,推荐3 以上
下面的条件三选一即可
- 1、公开发行版内核,可以访问 pylcc.openanolis.cn
- 2、公开发行版内核,已经从 http://pylcc.openanolis.cn/db/ 下载了 对应内核的db文件
- 3.1、环境上安装了gdb 版本大于 9,如果是x86 平台,可以直接从 http://pylcc.openanolis.cn/gdb/x64/gdb 下载
- 3.2、安装了对应内核的 vmlinux (结构化表达式依赖,非必须)
## 2.3、参数说明
```bash
usage: surftrace.py [-h] [-v VMLINUX] [-m MODE] [-r RIP] [-f FILE] [-g GDB]
[-F FUNC] [-o OUTPUT] [-l LINE] [-a ARCH] [-s] [-S]
[traces [traces ...]]
Trace ftrace kprobe events.
positional arguments:
trace set trace args.
optional arguments:
-h, --help show this help message and exit
-v VMLINUX, --vmlinux VMLINUX
set vmlinux path.
-m MODE, --mode MODE set arg parser, fro
-r RIP, --rip RIP set remote server ip, remote mode only.
-f FILE, --file FILE set input args path.
-g GDB, --gdb GDB set gdb exe file path.
-F FUNC, --func FUNC disasassemble function.
-o OUTPUT, --output OUTPUT
set output bash file
-l LINE, --line LINE get file disasemble info
-a ARCH, --arch ARCH set architecture.
-s, --stack show call stacks.
-S, --show only show expressions.
```
-f: 从文件中读取表达式,适合大量配置的场景
-o: 将执行过程导出到脚本中
-a:指定cpu架构,涉及到寄存器转换,目前只支持x86_64/aarch64,不指定的话,会根据lscpu获取
-s:打印probe点调用栈,这是个全局开关
-S:只生成ftrace表达式,不下发到ftrace。该模式适合交叉调试场景,比如我们要想在树莓派上去probe 钩子,但是树莓派的资源空间有限,不可能去安装gdb和vmlinux。因此我们可以在宿主机上将结构化表达式转成ftrace表达式。然后在树莓派下发即可。
# 3、实战
我们以open anolis为例,将surftrace.py取下来
```
sudo sh -c su
chmod +x surftrace.py
```
## 3.1、追踪函数入口和返回位置
按Ctrl + C 停止
```bash
#./surftrace.py 'p _do_fork' 'r _do_fork'
echo 'p:f0 _do_fork ' >> /sys/kernel/debug/tracing/kprobe_events
echo 1 > /sys/kernel/debug/tracing/events/kprobes/f0/enable
echo 'r:f1 _do_fork ' >> /sys/kernel/debug/tracing/kprobe_events
echo 1 > /sys/kernel/debug/tracing/events/kprobes/f1/enable
echo 0 > /sys/kernel/debug/tracing/options/stacktrace
echo 1 > /sys/kernel/debug/tracing/tracing_on
<...>-1637241 [000] d... 7462686.335257: f0: (_do_fork+0x0/0x3a0)
<...>-1637241 [000] d... 7462686.335323: f1: (SyS_clone+0x36/0x40 <- _do_fork)
systemd-1 [004] d... 7462686.854375: f0: (_do_fork+0x0/0x3a0)
systemd-1 [004] d... 7462686.854446: f1: (SyS_clone+0x36/0x40 <- _do_fork)
……
systemd-1 [004] d... 7462688.104383: f0: (_do_fork+0x0/0x3a0)
systemd-1 [004] d... 7462688.104464: f1: (SyS_clone+0x36/0x40 <- _do_fork)
^Cecho 0 > /sys/kernel/debug/tracing/events/kprobes/f0/enable
<...>-1637241 [000] d... 7462688.134451: f0: (_do_fork+0x0/0x3a0)
<...>-1637241 [000] d... 7462688.135278: f1: (SyS_clone+0x36/0x40 <- _do_fork)
echo 0 > /sys/kernel/debug/tracing/events/kprobes/f1/enable
<...>-1637241 [000] d... 7462688.155188: f1: (SyS_clone+0x36/0x40 <- _do_fork)
echo > /sys/kernel/debug/tracing/kprobe_events
echo 0 > /sys/kernel/debug/tracing/tracing_on
```
可以看到 surftrace支持多个probe,所有表达式要用单引号括起来,表达式中,第一段字母p 表示probe函数入口,r表示probe函数返回位置,第二段为函数符号,该符号必须要在 tracing/available_filter_functions 中可以查找到的
## 3.2、 获取函数入参
还是以_do_fork为例,我们可以查找到它的入参是:
```c
#ifdef CONFIG_FORK2
long _do_fork(struct task_struct *parent,
struct task_struct *source,
unsigned long clone_flags,
#else
long _do_fork(unsigned long clone_flags,
#endif
unsigned long stack_start,
unsigned long stack_size,
int __user *parent_tidptr,
int __user *child_tidptr,
unsigned long tls)
```
我们可以确认它的第一个入参类型是 struct task_struct,如果要获取任务名,即common,可以采用以下方法:
```bash
#./surftrace.py 'p _do_fork comm=%0->comm'
echo 'p:f0 _do_fork comm=+0xafc(%di):string ' >> /sys/kernel/debug/tracing/kprobe_events
echo 1 > /sys/kernel/debug/tracing/events/kprobes/f0/enable
echo 0 > /sys/kernel/debug/tracing/options/stacktrace
echo 1 > /sys/kernel/debug/tracing/tracing_on
<...>-1642046 [001] d... 7463503.175187: f0: (_do_fork+0x0/0x3a0) comm="surftrace.py"
systemd-1 [002] d... 7463503.606161: f0: (_do_fork+0x0/0x3a0) comm="systemd"
python-16819 [003] d... 7463504.383400: f0: (_do_fork+0x0/0x3a0) comm="python"
systemd-1 [002] d... 7463504.856166: f0: (_do_fork+0x0/0x3a0) comm="systemd"
<...>-1642087 [002] d... 7463506.031046: f0: (_do_fork+0x0/0x3a0) comm="sh"
<...>-1642087 [002] d... 7463506.031363: f0: (_do_fork+0x0/0x3a0) comm="sh"
systemd-1 [004] d... 7463506.106159: f0: (_do_fork+0x0/0x3a0) comm="systemd"
^Cecho 0 > /sys/kernel/debug/tracing/events/kprobes/f0/enable
<...>-1642046 [001] d... 7463506.356102: f0: (_do_fork+0x0/0x
没有合适的资源?快使用搜索试试~ 我知道了~
sysak工具开源版本
共860个文件
c:144个
h:122个
makefile:95个
需积分: 10 0 下载量 38 浏览量
2023-01-14
20:56:38
上传
评论
收藏 491.19MB ZIP 举报
温馨提示
sysak工具
资源推荐
资源详情
资源评论
收起资源包目录
sysak工具开源版本 (860个子文件)
libnet.so.9.0.0 481KB
libnet.so.9 481KB
libnet.a 994KB
libbpf.a 588KB
Makefile.am 303B
AUTHORS 819B
AUTHORS 384B
make.bak 411B
bpftool 2.34MB
cJSON.c 79KB
cJSON.c 79KB
output_print.c 40KB
mod_cgroup.c 38KB
sysak.c 23KB
syshung_detector.c 21KB
pagescan.c 20KB
tcpping.c 17KB
appnoise.c 17KB
foxTSDB.c 17KB
mod_squid.c 17KB
foxTSDB.c 17KB
schedmoni.c 15KB
framework.c 15KB
appnoise.bpf.c 15KB
config.c 12KB
irqoff.c 12KB
syscall_helpers.c 12KB
tsar.c 12KB
mod_haproxy.c 11KB
mod_io.c 11KB
nosched.c 11KB
schedmoni.bpf.c 11KB
workqlatency.c 10KB
mod_nginx.c 10KB
beaver.c 10KB
runqslower.c 10KB
syscall_slow.c 9KB
main.c 8KB
json_format.c 8KB
apps.c 8KB
mod_lvs.c 7KB
drop.bpf.c 7KB
icmp.bpf.c 7KB
reclaimhung.c 7KB
collect.c 7KB
common.c 7KB
hw_event.c 7KB
tracesig.c 7KB
httpserver.c 7KB
output_nagios.c 6KB
memcg_usage.c 6KB
beeQ.c 6KB
syscall_slow.bpf.c 6KB
mod_proc.c 6KB
movability.c 6KB
mod_percpu.c 6KB
main.c 6KB
output_db.c 6KB
zero_subpage.c 6KB
nosched.bpf.c 5KB
reclaimhung.bpf.c 5KB
pidComm.c 5KB
mod_jitter.c 5KB
fanotifytrace.c 5KB
workqlatency.bpf.c 5KB
format_json.c 5KB
slab.c 5KB
mod_cpu.c 5KB
kvmexittime.c 5KB
runlatency.c 5KB
parser.c 5KB
cpuacct_load.c 4KB
irqoff.c 4KB
acltrace.c 4KB
mod_tcpx.c 4KB
mod_apache.c 4KB
slab.c 4KB
mod_partition.c 4KB
mod_mem.c 4KB
main.c 4KB
mod_load.c 4KB
kvmexittime.bpf.c 4KB
output_warn.c 4KB
main.c 4KB
mod_ncpu.c 4KB
mod_traffic.c 4KB
runqslower.bpf.c 4KB
irqoff.bpf.c 4KB
fragement.c 4KB
mod_vmevent.c 4KB
bpfsample.c 3KB
page.c 3KB
fanotify_sample.c 3KB
mod_tcp.c 3KB
mod_scheddelay.c 3KB
ecs_sender.bpf.c 3KB
ecs_sender_compat.bpf.c 3KB
runqslow.c 3KB
tcpping.bpf.c 3KB
check.c 3KB
共 860 条
- 1
- 2
- 3
- 4
- 5
- 6
- 9
资源评论
快乐肥宅sMiLe
- 粉丝: 0
- 资源: 3
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- 基于matlab实现用有限元法计算电磁场的Matlab工具 .rar
- 基于matlab实现有限元算法 计算电磁场问题 边界条件包括第一类边界和第二类边界.rar
- 基于matlab实现用于计算不同车重下的电动汽车动力性和经济性.rar
- 基于matlab实现遗传算法求解多车场车辆路径问题 有多组算例可以用.rar
- 浏览器.apk
- 基于matlab实现是一个matlab中的power system 中搭建的一个模型
- 基于JSP毕业设计-教学管理系统(源代码+论文).zip
- 基于JSP毕业设计-家政管理系统-毕业设计.zip
- 基于Python实现淘宝商品评论采集(含逆向)源代码
- 基于matlab实现多目标进化算法NSGAⅡ&Matlab讲解.rar
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功