﻿# ftrace内核追踪指南

## 一、ftrace概述
ftrace是Linux内核提供的强大追踪工具，可以用于追踪内核函数调用、调度延迟、中断延迟、系统调用延迟等性能问题。ftrace可以帮助你：
- 追踪内核函数的调用次数和执行时间
- 分析调度延迟和中断延迟
- 排查系统调用延迟问题
- 分析内核性能瓶颈

## 二、ftrace基础使用

### 1. 挂载debugfs
ftrace通常挂载在`/sys/kernel/debug/tracing/`目录下，如果没有挂载，可以手动挂载：
```bash
mount -t debugfs nodev /sys/kernel/debug
```

### 2. 查看可用的追踪器
```bash
cd /sys/kernel/debug/tracing/
cat available_tracers
```

常见的追踪器：
- `function`：追踪函数调用
- `function_graph`：追踪函数调用图
- `irqsoff`：追踪中断关闭延迟
- `preemptoff`：追踪抢占关闭延迟
- `wakeup`：追踪进程唤醒延迟
- `sched_switch`：追踪调度切换

### 3. 基本追踪命令

#### 追踪内核函数调用
```bash
# 选择function追踪器
echo function > current_tracer
# 设置要追踪的函数（支持通配符）
echo '*sys*' > set_ftrace_filter
# 开始追踪
echo 1 > tracing_on
# 运行一段时间后停止追踪
echo 0 > tracing_on
# 查看追踪结果
cat trace
```

#### 追踪函数调用图
```bash
# 选择function_graph追踪器
echo function_graph > current_tracer
# 设置要追踪的函数
echo '*sys*' > set_ftrace_filter
# 开始追踪
echo 1 > tracing_on
# 查看追踪结果
cat trace
```

## 三、调度延迟追踪

调度延迟是指从进程可运行到开始执行之间的时间，是性能分析的重要指标。

### 1. 追踪调度延迟
```bash
cd /sys/kernel/debug/tracing/
# 启用sched_switch追踪
echo 1 > events/sched/sched_switch/enable
# 启用sched_wakeup追踪
echo 1 > events/sched/sched_wakeup/enable
# 启用sched_wakeup_new追踪
echo 1 > events/sched/sched_wakeup_new/enable
# 开始追踪
echo 1 > tracing_on
# 运行一段时间后停止追踪
echo 0 > tracing_on
# 查看调度延迟分析
cat trace | grep -E "sched_switch|sched_wakeup"
```

### 2. 使用kernelshark可视化调度延迟
kernelshark是ftrace的图形界面工具，可以更直观地分析调度延迟：
```bash
# 安装kernelshark
sudo apt install kernelshark
# 生成追踪数据
echo 1 > events/sched/sched_switch/enable
echo 1 > events/sched/sched_wakeup/enable
echo 1 > tracing_on
sleep 10
echo 0 > tracing_on
cp trace /tmp/trace.data
# 使用kernelshark分析
kernelshark /tmp/trace.data
```

## 四、中断延迟追踪

中断延迟是指从中断发生到中断处理程序开始执行之间的时间，也是性能分析的重要指标。

### 1. 追踪中断延迟
```bash
cd /sys/kernel/debug/tracing/
# 启用irq_handler_entry和irq_handler_exit追踪
echo 1 > events/irq/irq_handler_entry/enable
echo 1 > events/irq/irq_handler_exit/enable
# 启用irq_softirq_entry和irq_softirq_exit追踪
echo 1 > events/softirq/softirq_entry/enable
echo 1 > events/softirq/softirq_exit/enable
# 开始追踪
echo 1 > tracing_on
# 运行一段时间后停止追踪
echo 0 > tracing_on
# 查看中断延迟分析
cat trace | grep -E "irq_handler|softirq"
```

### 2. 追踪中断关闭延迟
```bash
cd /sys/kernel/debug/tracing/
# 选择irqsoff追踪器
echo irqsoff > current_tracer
# 开始追踪
echo 1 > tracing_on
# 运行一段时间后停止追踪
echo 0 > tracing_on
# 查看中断关闭延迟结果
cat trace
```

## 五、系统调用延迟追踪

系统调用延迟是指从用户态发起系统调用到内核态执行完成返回用户态之间的时间。

### 1. 追踪系统调用延迟
```bash
cd /sys/kernel/debug/tracing/
# 启用sys_enter和sys_exit追踪
echo 1 > events/syscalls/sys_enter/enable
echo 1 > events/syscalls/sys_exit/enable
# 开始追踪
echo 1 > tracing_on
# 运行一段时间后停止追踪
echo 0 > tracing_on
# 查看系统调用延迟分析
cat trace | grep -E "sys_enter|sys_exit"
```

### 2. 统计系统调用执行时间
```bash
# 使用perf工具统计系统调用执行时间
perf stat -e syscalls:sys_enter_read,syscalls:sys_exit_read ./your_program
```

## 六、ftrace高级使用

### 1. 过滤追踪函数
```bash
# 只追踪特定函数
echo 'vfs_read' > set_ftrace_filter
# 排除特定函数
echo '!vfs_write' > set_ftrace_filter
# 查看当前过滤的函数
cat set_ftrace_filter
```

### 2. 追踪指定进程
```bash
# 只追踪指定PID的进程
echo <pid> > set_ftrace_pid
# 清除PID过滤
echo 0 > set_ftrace_pid
```

### 3. 保存和加载追踪配置
```bash
# 保存当前追踪配置
echo 1 > options/func_stack_trace
echo trace > /tmp/ftrace.trace
# 加载追踪配置
echo function > current_tracer
echo '*sys*' > set_ftrace_filter
echo 1 > tracing_on
```

## 七、常见ftrace命令总结

| 命令 | 说明 |
|------|------|
| `echo function > current_tracer` | 选择function追踪器 |
| `echo function_graph > current_tracer` | 选择function_graph追踪器 |
| `echo irqsoff > current_tracer` | 选择irqsoff追踪器 |
| `echo '*sys*' > set_ftrace_filter` | 设置要追踪的函数 |
| `echo 1 > tracing_on` | 开始追踪 |
| `echo 0 > tracing_on` | 停止追踪 |
| `cat trace` | 查看追踪结果 |
| `cat trace_pipe` | 实时查看追踪结果 |

## 八、参考资料
1. Linux内核官方文档：https://www.kernel.org/doc/html/latest/trace/ftrace.html
2. 《Linux内核调试与优化》 陈莉君
3. https://www.brendangregg.com/ftrace.html
4. https://man7.org/linux/man-pages/man8/trace-cmd.8.html
