Linux Ftrace介绍

文章目录

  • 一、简介
  • 二、内核函数调用跟踪
    • 参考链接:

一、简介

Ftrace 是 Linux 官方提供的跟踪工具,在 Linux 2.6.27 版本中引入。Ftrace 可在不引入任何前端工具的情况下使用,让其可以适合在任何系统环境中使用。
Ftrace 可用来快速排查以下相关问题:

  • 特定内核函数调用的频次 (function)
  • 内核函数在被调用的过程中流程(调用栈) (function + stack)
  • 内核函数调用的子函数流程(子调用栈)(function graph)
  • 由于抢占导致的高延时路径等

Ftrace 跟踪工具由性能分析器(profiler)和跟踪器(tracer)两部分组成:

  • 性能分析器,用来提供统计和直方图数据(需要 CONFIG_ FUNCTION_PROFILER=y)
    • 函数性能分析
    • 直方图
  • 跟踪器,提供跟踪事件的详情:
    • 函数跟踪(function)
    • 跟踪点(tracepoint)
    • kprobe
    • uprobe
    • 函数调用关系(function_graph)
    • hwlat 等

除了操作原始的文件接口外,也有一些基于 Ftrace 的前端工具,比如 perf-tools 和 trace-cmd (界面 KernelShark)等。整体跟踪及前端工具架构图如下:
Linux Ftrace介绍_第1张图片
Ftrace 的使用的接口为 tracefs 文件系统,需要保证该文件系统进行加载:

$ sysctl -q kernel.ftrace_enabled=1
$ mount -t tracefs tracefs /sys/kernel/tracing

$ mount -t debugfs,tracefs
tracefs on /sys/kernel/tracing type tracefs (rw,nosuid,nodev,noexec,relatime)
debugfs on /sys/kernel/debug type debugfs (rw,nosuid,nodev,noexec,relatime)
tracefs on /sys/kernel/debug/tracing type tracefs (rw,nosuid,nodev,noexec,relatime)

$ ls -F /sys/kernel/debug/tracing  # 完整目录如下图

Linux Ftrace介绍_第2张图片
tracing 目录下核心文件介绍如下表格,当前可仅关注黑体加粗的项,其他项可在需要的时候再进行回顾:

文件 描述
available_tracers 可用跟踪器,hwlat blk function_graph wakeup_dl wakeup_rt wakeup function nop,nop 表示不使用跟踪器
current_tracer 当前使用的跟踪器
function_profile_enabled 启用函数性能分析器
available_filter_functions 可跟踪的完整函数列表
set_ftrace_filter 选择跟踪函数的列表,支持批量设置,例如 tcp、tcptcp
set_ftrace_notrace 设置不跟踪的函数列表
set_event_pid 设置跟踪的 PID,表示仅跟踪 PID 程序的函数或者其他跟踪
tracing_on 是否启用跟踪,1 启用跟踪 0 关闭跟踪
trace_options 设置跟踪的选项
trace_stat(目录) 函数性能分析的输出目录
kprobe_events 启用 kprobe 的配置
uprobe_events 启用 uprobe 的配置
events ( 目录 ) 事件(Event)跟踪器的控制文件: tracepoint、kprobe、uprobe
trace 跟踪的输出 (Ring Buffer)
trace_pipe 跟踪的输出;提供持续不断的数据流,适用于程序进行读取

perf_tools 包含了一个复位所有 ftrace 选型的工具脚本,在跟踪不符合预期的情况下,建议先使用 reset-ftrace 进行复位,然后再进行测试。

二、内核函数调用跟踪

基于 Ftrace 的内核函数调用跟踪整体架构如下所示:
Linux Ftrace介绍_第3张图片
这里我们尝试对于内核中的系统调用函数 __arm64_sys_openat 进行跟踪(前面两个下划线),需要注意的是 __arm64_sys_openat 是在 arm64 结构体系下 sys_openat 系统调用的包装,如果在 x86_64 架构下则为 __x64_sys_openat() ,由于我们本地的电脑是 M1 芯片,所以演示的样例以 arm64 为主。

在不同的体系结构下,可以在 /proc/kallsym 文件中搜索确认。

后续的目录,如无特殊说明,都默认位于 /sys/kernel/debug/tracing/ 根目录。

# 使用 function 跟踪器,并将其设置到 current_tracer
$ sudo echo function > current_tracer

# 将跟踪函数 __arm64_sys_openat 设置到 set_ftrace_filter 文件中
$ sudo echo __arm64_sys_openat > set_ftrace_filter

# 开启全局的跟踪使能
$ sudo echo 1 > tracing_on

# 运行 ls 命令触发 sys_openat 系统调用,新的内核版本中直接调用 sys_openat
$ ls -hl 

# 关闭
$ sudo echo 0 > tracing_on
$ sudo echo nop > current_tracer

# 需要主要这里的 echo 后面有一个空格,即 “echo+ 空格>" 
$ sudo echo  > set_ftrace_filter 

# 通过 cat trace 文件进行查看
$ sudo cat trace
# tracer: function
#
# entries-in-buffer/entries-written: 224/224   #P:4
#
#                                _-----=> irqs-off
#                               / _----=> need-resched
#                              | / _---=> hardirq/softirq
#                              || / _--=> preempt-depth
#                              ||| /     delay
#           TASK-PID     CPU#  ||||   TIMESTAMP  FUNCTION
#              | |         |   ||||      |         |
            sudo-15099   [002] .... 29469.444400: __arm64_sys_openat <-invoke_syscall
            sudo-15099   [002] .... 29469.444594: __arm64_sys_openat <-invoke_syscall

我们可以看到上述的结果表明了函数调用的任务名称、PID、CPU、标记位、时间戳及函数名字。

在 perf_tools 工具集中的前端封装工具为 functrace ,需要注意的是该工具默认不会设置 tracing_on 为 1, 需要在启动前进行设置,即 ”echo 1 > tracing_on“。

perf_tools 工具集中 kprobe 也可以实现类似的效果,底层基于 kprobe 机制实现,ftrace 机制中的 kprobe 在后续章节会详细介绍。

参考链接:

  1. 问题排查利器:Linux 原生跟踪工具 Ftrace 必知必会
  2. perf-tools使用方法

你可能感兴趣的:(linux)