源码编译
Linux跟踪技术
在 Linux 中,挂载(Mount)是指将一个文件系统关联到目录树中的某个目录,使该目录成为访问该文件系统的入口点。换句话说,挂载操作使用户能够通过目录路径访问存储设备、网络共享或虚拟文件系统。
ftrace
问题排查利器:Linux 原生跟踪工具 Ftrace 必知必会 | Head First eBPF
基于这个机制,进行hookFTRACE
- ftrace 的基本概念
ftrace
是 Linux 内核的一个跟踪框架,旨在捕获内核函数调用的详细信息。通过使用 ftrace
,用户可以跟踪函数调用、内存使用、内核事件等。它的工作原理是利用内核的跟踪点(tracepoints),这些跟踪点是在内核代码的特定位置插入的标记,通过这些标记可以记录和监控内核行为。
- ftrace 的核心功能
函数跟踪(Function Tracing):
ftrace
能够记录内核函数的进入、退出及其调用栈信息,帮助开发者了解内核函数的执行情况。跟踪点(Tracepoints):
ftrace
使用内核中的 tracepoints,这些是内核代码中特定位置的标记,允许在这些位置插入跟踪信息。时间戳:
ftrace
记录时间戳信息,帮助用户评估函数调用的延迟和性能。事件跟踪:
ftrace
能跟踪内核的各种事件,比如中断、系统调用、调度、I/O 等。性能分析:它可以提供内核函数执行的详细时间信息,从而分析系统瓶颈,做出优化决策。
debugfs
1 | Curve@qqxx:~/桌面/save$ mount | grep debugfs |
**debugfs **
debugfs
是一个特殊的文件系统,专门用于调试和获取内核的运行状态信息。内核态进行交互。它可以提供:
- 内核内部状态的实时信息.调试信息(如
ftrace
、kprobes
、kmemleak
等).运行时调整内核参数。开发人员自定义的调试接口
debugfs 的特性
轻量级:debugfs
仅在需要时加载,不影响正常系统运行。动态更新:信息是实时的,可以动态查看和修改。
用户态访问:用户可以通过常规的文件操作(如 cat
、echo
)读取或修改数据。内核模块支持:很多内核模块会在 debugfs
中提供调试信息,例如 ftrace
、drm
、i915
等。
tracefs
1 | Curve@qqxx:~/桌面/save$ mount | grep tracefs |
tracefs
是 Linux 内核中的一个专门用于跟踪和调试的虚拟文件系统,主要用于 ftrace
(Function Tracer)。tracefs
提供了一种文件系统接口,允许用户直接访问和控制内核跟踪功能,而无需修改内核代码。
在 Linux 3.4 之前,ftrace
使用的是 debugfs
,但从 Linux 4.1 开始,tracefs
作为独立的文件系统引入,使 ftrace
的功能更加独立,并减少对 debugfs
的依赖。
available_filter_functions 包含所有可以被kprobe探测的函数列表 bcc操作的时候读取该文件列表
*_events表示正在检测的函数列表 (dynamic_events 所有列表集合 events目录是所有可hook点例如syscalls)
示例:使用uprobes去hook readline
找到 readline 函数地址
readelf -s /bin/bash | grep -E “readline$”
914: 00000000000d5700 201 FUNC GLOBAL DEFAULT 16 readline
将 readline 函数地址写入 uprobe_events,会在 uprobe_events 下创建目录 readline p表示uprobe
sudo bash -c ‘echo p:readline /bin/bash:0x00000000000d5700 %ip %ax > /sys/kernel/debug/tracing/uprobe_events’
查看写入内容
sudo cat /sys/kernel/debug/tracing/uprobe_events
p:uprobes/readline /bin/bash:0x00000000000d5700 arg1=%ip arg2=%ax
控制这里的 enable 来启动 hook 点
sudo ls /sys/kernel/debug/tracing/events/uprobes/
enable filter readline
启用或禁用 uprobes 跟踪事件 | 通过将1写入该文件,可以启用 uprobes 跟踪事件,并跟踪 readline 函数的调用
1 | sudo bash -c 'echo 1 > /sys/kernel/debug/tracing/events/uprobes/readline/enable' |
启用或禁用 ftrace 跟踪事件
1 | sudo bash -c 'echo 1 > /sys/kernel/debug/tracing/events/enable' |
启用或禁用 ftrace 跟踪功能
1 | sudo bash -c 'echo 1 > /sys/kernel/debug/tracing/tracing_on' |
读取日志输出
1 | sudo cat /sys/kernel/debug/tracing/trace_pipe | grep readline |
bash-4615 [006] DNZff 11978.430154: readline: (0x5e2c7fbbb700) arg1=0x5e2c7fbbb700 arg2=0x5e2c7fc0d1bd
bash-4615 [001] DNZff 11981.981392: readline: (0x5e2c7fbbb700) arg1=0x5e2c7fbbb700 arg2=0x5e2c7fc0d1bd
❗ 在启用 hook 时无法在添加其他 hook 点 ❗ 算是一个弊端 ❗
sudo bash -c ‘echo p:readline /bin/bash:0x00000000000d5690 %ip %ax > /sys/kernel/debug/tracing/uprobe_events’
bash: 行 1: /sys/kernel/debug/tracing/uprobe_events: 设备或资源忙
清空 uprobes 与 kprobe 跟踪事件的设置
1 | sudo bash -c 'echo > /sys/kernel/debug/tracing/kprobe_events' |
perf
linux性能分析工具perf (ebpf使用它的接口)。
sudo perf top 列举正在使用的系统调用。
sudo perf stat -e ‘syscalls:sys_enter_*’ -a sleep 5 统计系统调用的次数。
sudo perf ftrace -F 对ftrace的包装 ,列出可被跟踪函数
sudo perf record ls 采样ls 收集信息
sudo perf script/report 查看信息(Q退出)
sudo strace -e openat,perf_event_open perf record -e ‘syscalls:sys_enter_openat’ -aR sleep2
perf事件源和pmu,pmu是性能管理单元