ftrace function 实践例子

ftrace function demo

一、编译期准备:插入 mcount 调用

条件:

内核 .config 含有:

CONFIG_FUNCTION_TRACER=y
CONFIG_DYNAMIC_FTRACE=y

作用:

  • 编译时自动为所有函数前插入 call mcount。
  • gcc -pg 参数实现此目的。

示例:

do_dentry_open:
    call mcount
    ...

二、运行时 patch:替换 mcount 为 ftrace_caller

动态 ftrace 会用 ftrace_make_call()call mcount 替换为 call ftrace_caller,从而跳转到 ftrace 注册的钩子。

三、执行流程(调用发生时)

call do_dentry_open 为例,函数执行触发流程如下:

    do_dentry_open()
       |
       |---> call ftrace_caller  <-- 原为 mcount,已被 patch
               |
               |---> ftrace_ops_list
                          |
                          |---> your callback_func(ip, parent_ip, ops, regs)

函数分发器(Trampoline):

void ftrace_caller(void)
{
    save_regs_to_stack();
    call all ftrace_ops->func();
    restore_regs_from_stack();
    jmp original_func_body;
}

四、demo

mount -t debugfs none /sys/kernel/debug

# 设置 tracer 类型
echo function > /sys/kernel/debug/tracing/current_tracer

# 设置要跟踪的函数
echo do_dentry_open > /sys/kernel/debug/tracing/set_ftrace_filter

# 清空 trace buffer
echo > /sys/kernel/debug/tracing/trace

# 启动跟踪
echo 1 > /sys/kernel/debug/tracing/tracing_on

# 运行一个触发 open 的命令
ls / > /dev/null

# 查看结果
cat /sys/kernel/debug/tracing/trace

# 停止跟踪
echo 0 > /sys/kernel/debug/tracing/tracing_on

执行cat /sys/kernel/debug/tracing/trace,将看见类似如下内容:

~ # cat /sys/kernel/debug/tracing/trace
# tracer: function
#
# entries-in-buffer/entries-written: 6/6   #P:2
#
#                                _-----=> irqs-off
#                               / _----=> need-resched
#                              | / _---=> hardirq/softirq
#                              || / _--=> preempt-depth
#                              ||| / _-=> migrate-disable
#                              |||| /     delay
#           TASK-PID     CPU#  |||||  TIMESTAMP  FUNCTION
#              | |         |   |||||     |         |
              sh-101     [001] .....    33.388469: do_dentry_open <-path_openat
              sh-101     [001] .....    37.068001: do_dentry_open <-path_openat
              ls-106     [000] .....    37.069901: do_dentry_open <-path_openat
              ls-106     [000] .....    37.072422: do_dentry_open <-path_openat
             cat-107     [000] .....    41.571282: do_dentry_open <-path_openat
             cat-107     [000] .....    41.571735: do_dentry_open <-path_openat

字段说明:

字段含义
ls-106任务名和PID
[000]运行在哪个CPU核上
....中断、抢占等状态标志位(见下)
37.069901时间戳(秒)
do_dentry_open当前调用的函数名(从符号表解析)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值