ftrace

以下是使用 Ftrace 调试 Linux 内核的完整示例,涵盖常用场景和操作步骤:


1. 基础函数跟踪

场景:跟踪 schedule() 函数的调用情况。
# 挂载 tracefs(如果未自动挂载)
mount -t tracefs nodev /sys/kernel/tracing

# 进入 trace 目录
cd /sys/kernel/tracing

# 启用函数跟踪器
echo function > current_tracer

# 设置要跟踪的函数
echo schedule > set_ftrace_filter

# 开始记录
echo 1 > tracing_on

# 触发一些操作(例如运行一个进程)
sleep 1

# 停止记录
echo 0 > tracing_on

# 查看结果
cat trace

输出示例

# tracer: function
#
#           TASK-PID    CPU#    TIMESTAMP  FUNCTION
#              | |        |        |         |
           sleep-1234    [001]  12345.678901: schedule <-do_nanosleep
           bash-5678     [002]  12345.678902: schedule <-schedule_timeout

2. 跟踪特定进程

场景:仅跟踪 PID 为 1234 的进程调用的函数。
# 设置 PID 过滤
echo 1234 > set_ftrace_pid

# 启用跟踪
echo function > current_tracer
echo 1 > tracing_on

# 查看结果
cat trace

3. 跟踪函数调用关系(函数图)

场景:分析 do_sys_open() 的调用栈。
# 启用函数图跟踪器
echo function_graph > current_tracer

# 设置跟踪函数
echo do_sys_open > set_graph_function

# 开始记录
echo 1 > tracing_on

# 执行文件操作(如 `cat /proc/version`)
cat /proc/version

# 停止并查看
echo 0 > tracing_on
cat trace

输出示例

# tracer: function_graph
#
# CPU  DURATION                  FUNCTION CALLS
# |     |   |                     |   |   |   |
 1)   1.234 us    |  do_sys_open();
 1)               |  getname() {
 1)   0.567 us    |    getname_flags();
 1)   1.234 us    |  }
 1)               |  vfs_open() {
 1)   0.456 us    |    do_dentry_open();
 1)   2.345 us    |  }

4. 跟踪内核模块函数

场景:跟踪自定义模块 my_module 中的 my_func()
# 确保模块已加载且符号可见
grep my_func /proc/kallsyms

# 设置过滤器
echo ':mod:my_module' > set_ftrace_filter
echo my_func >> set_ftrace_filter

# 启用跟踪
echo function > current_tracer
echo 1 > tracing_on

# 触发模块函数调用
# ...

# 查看结果
cat trace

5. 跟踪中断事件

场景:跟踪 IRQ 事件和中断处理函数。
# 启用中断事件跟踪
echo irq:* > set_event

# 同时跟踪中断处理函数
echo handle_irq_event_percpu > set_ftrace_filter

# 开始记录
echo 1 > tracing_on

# 触发中断(如网卡收包)
ping -c 1 google.com

# 停止并查看
echo 0 > tracing_on
cat trace

输出示例

# tracer: function
#
#                              _-----=> irqs-off
#                             / _----=> need-resched
#                            | / _---=> hardirq/softirq
#                            || / _--=> preempt-depth
#                            ||| /     delay
#           TASK-PID   CPU#  ||||   TIMESTAMP  FUNCTION
#              | |       |   ||||      |         |
           <idle>-0     [000] d...  1234.567890: irq_handler_entry: irq=19 name=eth0
           <idle>-0     [000] d...  1234.567891: handle_irq_event_percpu <-handle_irq_event

6. 跟踪内核锁事件

场景:分析自旋锁的竞争情况。
# 启用锁事件跟踪
echo lock:* > set_event

# 开始记录
echo 1 > tracing_on

# 触发锁操作(如并发访问驱动)
# ...

# 停止并查看
echo 0 > tracing_on
cat trace | grep spin_lock

7. 使用 trace-cmd 简化操作

场景:一键记录并分析函数调用。
# 安装 trace-cmd
sudo apt install trace-cmd

# 记录 schedule 函数的调用
trace-cmd record -p function -l schedule

# 生成报告
trace-cmd report

8. 高级技巧

(1) 过滤函数调用时长
# 只显示执行时间 > 100us 的函数
echo duration > trace_options
echo 100 > tracing_thresh  # 单位微秒
(2) 跟踪内核定时器
echo hrtimer:* > set_event
echo timer:* >> set_event
(3) 保存跟踪结果
cat trace > /tmp/ftrace.log

9. 恢复默认配置

# 停止跟踪
echo 0 > tracing_on

# 重置跟踪器
echo nop > current_tracer

# 清空过滤器
echo > set_ftrace_filter
echo > set_event

总结表

场景关键命令输出内容
基础函数跟踪echo function > current_tracer函数调用顺序和时间戳
函数调用栈echo function_graph > current_tracer函数嵌套关系和耗时
进程过滤echo PID > set_ftrace_pid仅目标进程的函数调用
模块函数跟踪echo ':mod:module' > set_ftrace_filter模块内特定函数的调用
中断跟踪echo irq:* > set_event中断触发和处理流程

通过灵活组合这些方法,可以高效诊断内核行为、性能瓶颈和竞态条件问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值