文章目录
跟踪器与事件使用举例
一、跟踪器使用实例
1.1 function 跟踪器
功能:记录函数调用入口
bash
# 示例1:基本使用
cd /sys/kernel/debug/tracing
echo 0 > tracing_on
echo > trace
echo function > current_tracer
echo 1 > tracing_on
# 执行一些操作
ls -la /tmp
echo 0 > tracing_on
cat trace | head -20
# 输出示例:
# bash-1234 [001] .... 4567.890123: vfs_open <-do_sys_open
# bash-1234 [001] .... 4567.890124: do_dentry_open <-vfs_open
过滤特定函数:
bash
# 只跟踪文件系统相关函数
echo '*!*' > set_ftrace_filter # 先清空
echo 'vfs_*' 'ext4_*' 'xfs_*' > set_ftrace_filter
# 排除特定函数
echo '*spin*' '!*lock*' > set_ftrace_notrace
1.2 function_graph 跟踪器
功能:记录函数调用图和执行时间
bash
# 分析 read 系统调用的完整调用链
cd /sys/kernel/debug/tracing
echo 0 > tracing_on
echo > trace
echo function_graph > current_tracer
# 设置深度限制
echo 3 > max_graph_depth
# 设置要跟踪的函数
echo 'vfs_read' > set_graph_function
echo 1 > tracing_on
cat /dev/null
echo 0 > tracing_on
cat trace | head -30
# 输出示例:
# CPU DURATION FUNCTION CALLS
# 0) | vfs_read() {
# 0) 0.085 us | rw_verify_area();
# 0) | __vfs_read() {
# 0) 0.150 us | rw_verify_area();
# 0) | new_sync_read() {
# 0) | ext4_file_read_iter() {
# 0) 0.120 us | generic_file_read_iter();
# 0) 0.085 us | touch_atime();
# 0) 0.120 us | pagecache_isize_extended();
# 0) 1.250 us | }
# 0) 2.120 us | }
# 0) 3.520 us | }
# 0) 3.850 us | }
跟踪进程PID:
bash
# 只跟踪特定进程
pidof bash
# 输出:1234
echo 1234 > set_ftrace_pid
echo 1 > tracing_on
# 在另一个终端执行 bash 命令
echo 0 > tracing_on
1.3 irqsoff 跟踪器
功能:测量中断关闭时间
bash
# 测量中断关闭延迟
cd /sys/kernel/debug/tracing
echo 0 > tracing_on
echo > trace
echo irqsoff > current_tracer
echo 1 > options/function-trace
echo 1 > tracing_on
# 执行可能长时间关中断的操作
# 例如:执行大量内存操作
dd if=/dev/zero of=/tmp/test bs=1M count=100
# 或:编译大项目
make -j8
echo 0 > tracing_on
cat trace
# 输出示例:
# 会显示中断关闭的最大时间和相关调用栈
# 关键行:irqs disabled for 5.123 ms
二、事件使用实例
2.1 调度器事件
场景:分析进程调度行为
bash
# 启用调度相关事件
cd /sys/kernel/debug/tracing
echo 0 > tracing_on
echo > trace
echo 1 > events/sched/sched_switch/enable
echo 1 > events/sched/sched_wakeup/enable
echo 1 > events/sched/sched_migrate_task/enable
# 设置过滤器:只跟踪特定进程
echo 'prev_comm == "bash" || next_comm == "bash"' > events/sched/sched_switch/filter
echo 'comm == "bash"' > events/sched/sched_wakeup/filter
echo 1 > tracing_on
# 在另一个终端执行命令
ls -la
sleep 0.1
ls -la
echo 0 > tracing_on
cat trace | head -20
# 输出示例:
# bash-1234 [000] d..3 4567.890123: sched_switch: prev_comm=bash prev_pid=1234 next_comm=ksoftirqd/0 next_pid=89
# bash-1234 [000] d..3 4567.890456: sched_wakeup: comm=bash pid=1234 prio=120 target_cpu=000
统计调度次数:
bash
# 启用直方图统计
echo 'hist:keys=common_pid,prev_comm:vals=hitcount' > events/sched/sched_switch/trigger
echo 1 > tracing_on
sleep 5
echo 0 > tracing_on
cat events/sched/sched_switch/hist
# 输出:
# 显示每个进程的调度次数统计
2.2 内存事件
场景:监控内存分配
bash
# 跟踪大内存分配
cd /sys/kernel/debug/tracing
echo 0 > tracing_on
echo > trace
echo 1 > events/kmem/kmalloc/enable
echo 1 > events/kmem/kfree/enable
# 设置过滤器:只跟踪大于4KB的分配
echo 'bytes_alloc > 4096' > events/kmem/kmalloc/filter
# 记录调用栈
echo 'stacktrace' > events/kmem/kmalloc/trigger
echo 1 > tracing_on
# 执行可能分配大内存的操作
cat /dev/urandom | head -c 1048576 > /tmp/largefile
# 或启动内存密集型应用
echo 0 > tracing_on
cat trace | head -30
# 输出示例:
# 显示大内存分配的调用栈
监控内存泄漏:
bash
# 跟踪分配但未释放的内存
echo 1 > events/kmem/kmalloc/enable
echo 1 > events/kmem/kfree/enable
echo 'stacktrace' > events/kmem/kmalloc/trigger
echo 'trace_on' > events/kmem/kmalloc/trigger
echo 1 > tracing_on
# 运行可疑代码
echo 0 > tracing_on
# 分析未配对的kmalloc
2.3 系统调用事件
场景:监控特定系统调用
bash
# 跟踪文件打开操作
cd /sys/kernel/debug/tracing
echo 0 > tracing_on
echo > trace
echo 1 > events/syscalls/sys_enter_open/enable
echo 1 > events/syscalls/sys_enter_openat/enable
echo 1 > events/syscalls/sys_exit_open/enable
echo 1 > events/syscalls/sys_exit_openat/enable
# 设置过滤器:只跟踪特定文件
echo 'filename ~ "*.conf"' > events/syscalls/sys_enter_open/filter
echo 'filename ~ "*.conf"' > events/syscalls/sys_enter_openat/filter
echo 1 > tracing_on
# 执行操作
cat /etc/nginx/nginx.conf
cat /etc/ssh/sshd_config
echo 0 > tracing_on
cat trace | head -20
# 输出示例:
# bash-1234 [001] .... 4567.890123: sys_open(filename: /etc/nginx/nginx.conf, flags: 0, mode: 0)
跟踪失败的open调用:
bash
echo 'ret < 0' > events/syscalls/sys_exit_open/filter
echo 1 > tracing_on
# 尝试打开不存在的文件
cat /nonexistent/file
echo 0 > tracing_on
cat trace
三、总结对比
| 场景 | 推荐方案 | 命令示例 |
|---|---|---|
| 函数调用分析 | function_graph跟踪器 | echo function_graph > current_tracer |
| 性能热点定位 | function跟踪器+过滤 | echo 'vfs_*' > set_ftrace_filter |
| 延迟问题排查 | irqsoff/wakeup跟踪器 | echo wakeup > current_tracer |
| 调度行为监控 | sched事件 | echo 1 > events/sched/enable |
| 内存使用分析 | kmem事件 | echo 1 > events/kmem/kmalloc/enable |
| 系统调用跟踪 | syscalls事件 | echo 1 > events/syscalls/enable |
| 网络问题诊断 | net/skb事件 | echo 1 > events/skb/kfree_skb/enable |
| 生产环境监控 | 事件+过滤器 | echo 'latency > 1000000' > filter |
| 实时问题捕获 | 触发器+快照 | echo 'snapshot' > trigger |
关键经验:
- 从简开始:先用事件,不够再用跟踪器
- 精确过滤:使用过滤器减少数据量和开销
- 控制时长:生产环境跟踪时间不宜过长
- 实例隔离:多任务跟踪使用实例
- 及时清理:跟踪后恢复默认设置