当前位置: 首页 > news >正文

【Ftrace 专栏】Ftrace 基础使用

Ftrace 基础使用

文章目录

  • Ftrace 基础使用
    • 1、查看函数被执行
    • 2、查看模块的执行函数
    • 3、查看函数向上的调用栈
    • 4、查看执行代码流程
    • 5、查看函数执行时间
    • 6、查看函数执行时间 和函数向下执行流
    • 7、查看函数执行时间 和 函数向下执行流 和函数向上执行流
    • 8、使用option
    • 9、使用set_ftrace_filter
    • 10、使用kprobe
      • 1、数据结构
      • 2、数据类型 和 结构体偏移
      • 3、添加和使用kprobe
      • 4、输出日志

https://www.yuque.com/wangjianfeng-8fxdf/gaf2xs/gbk1zc#yRQlC

1、查看函数被执行

  • 方式1、使用function_tracer
cat ./available_filter_functions | grep blk_update_request
#! /bin/bashCURRENT_DIR=$(pwd)
SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)
TRACE_DIR='/sys/kernel/debug/tracing/'cd ${TRACE_DIR}
echo 0 > ./tracing_on && echo > ./trace
echo blk_update_request > ./set_ftrace_filterecho function > ./current_tracer # turn on
echo 1 > ./tracing_on
${SCRIPT_DIR}/run_test.sh && cp ./trace ${SCRIPT_DIR}/trace_test.log
echo 0 > ./tracing_on
echo nop > ./current_tracer # turn offecho !blk_update_request >> ./set_ftrace_filter
cat ${SCRIPT_DIR}/trace_test.logcd ${CURRENT_DIR}
exec "$@"
  • 方式2、kprobe event
cat ./available_filter_functions  | grep blk_update_request
# echo 'p blk_update_request' > ./kprobe_events
## cat ./kprobe_events
### p:kprobes/p_blk_update_request_0 blk_update_request
  • 参考脚本
#! /bin/bashCURRENT_DIR=$(pwd)
SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)
TRACE_DIR='/sys/kernel/debug/tracing/'cd ${TRACE_DIR}
echo 0 > ./tracing_on && echo > ./trace
echo 'p blk_update_request' > ./kprobe_eventsecho 1 > ./events/kprobes/p_blk_update_request_0/enable # turn on
echo 1 > ./tracing_on
${SCRIPT_DIR}/run_test.sh && cp ./trace ${SCRIPT_DIR}/trace_test.log
echo 0 > ./tracing_on
echo 0 > ./events/kprobes/p_blk_update_request_0/enable # turn offecho '-:p_blk_update_request_0' >> kprobe_events
cat ${SCRIPT_DIR}/trace_test.logcd ${CURRENT_DIR}
exec "$@"

2、查看模块的执行函数

#! /bin/bashCURRENT_DIR=$(pwd)
SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)
TRACE_DIR='/sys/kernel/debug/tracing/'cd ${TRACE_DIR}
echo 0 > ./tracing_on && echo > ./trace
echo '*:mod:my_modul' > ./set_ftrace_filterecho function > ./current_tracer # turn on
echo 1 > ./tracing_on
${SCRIPT_DIR}/run_test.sh && cp ./trace ${SCRIPT_DIR}/trace_test.log
echo 0 > ./tracing_on
echo nop > ./current_tracer # turn offecho '!*:mod:ext4' >> ./set_ftrace_filter
cat ${SCRIPT_DIR}/trace_test.logcd ${CURRENT_DIR}
exec "$@"

3、查看函数向上的调用栈

  • 方式1、使用function tracer
cat ./available_filter_functions | grep vfs_open
cat ./available_filter_functions | grep bio_add_page
#! /bin/bashCURRENT_DIR=$(pwd)
SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)
TRACE_DIR='/sys/kernel/debug/tracing/'cd ${TRACE_DIR}
echo 0 > ./tracing_on && echo > ./trace
echo bio_add_page > ./set_ftrace_filter
echo vfs_open >> ./set_ftrace_filter
echo 1 > ./options/func_stack_traceecho function > ./current_tracer # turn on
echo 1 > ./tracing_on
${SCRIPT_DIR}/run_test.sh && cp ./trace ${SCRIPT_DIR}/trace_test.log
echo 0 > ./tracing_on
echo nop > ./current_tracer # turn offecho 0 > ./options/func_stack_trace
echo !bio_add_page >> ./set_ftrace_filter
echo !vfs_open >> ./set_ftrace_filter
cat ${SCRIPT_DIR}/trace_test.logcd ${CURRENT_DIR}
exec "$@"
  • 方式2、使用kprobe event
cat ./available_filter_functions | grep vfs_open
# echo 'p vfs_open' > ./kprobe_events
## cat ./kprobe_events
### p:kprobes/p_vfs_open_0 vfs_open
#! /bin/bashCURRENT_DIR=$(pwd)
SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)
TRACE_DIR='/sys/kernel/debug/tracing/'cd ${TRACE_DIR}
echo nop > current_tracer
echo 0 > ./tracing_on && echo > ./trace
echo 'p vfs_open' > ./kprobe_events
echo 1 > ./options/stacktrace
# or
# echo 'stacktrace' > ./events/kprobes/p_vfs_open_0/triggerecho 1 > ./events/kprobes/p_vfs_open_0/enable # turn on
echo 1 > ./tracing_on
${SCRIPT_DIR}/run_test.sh && cp ./trace ${SCRIPT_DIR}/trace_test.log
echo 0 > ./tracing_on
echo 0 > ./events/kprobes/p_vfs_open_0/enable # turn off# echo '!stacktrace' >  ./events/kprobes/p_vfs_open_0/trigger
echo 0 > ./options/stacktrace
echo '-:p_vfs_open_0' >> kprobe_events
cat ${SCRIPT_DIR}/trace_test.logcd ${CURRENT_DIR}
exec "$@"
  • 方式3、一招制胜
#! /bin/bashCURRENT_DIR=$(pwd)
SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)
TRACE_DIR='/sys/kernel/debug/tracing/'cd ${TRACE_DIR}
echo nop > current_tracer
echo 0 > ./tracing_on && echo > ./traceecho 'blk_update_request:stacktrace' > ./set_ftrace_filter
echo 1 > ./tracing_on
${SCRIPT_DIR}/run_test.sh && cp ./trace ${SCRIPT_DIR}/trace_test.log
echo 0 > ./tracing_on
echo "!blk_update_request:stacktrace" > ./set_ftrace_filtercat ${SCRIPT_DIR}/trace_test.log
cd ${CURRENT_DIR}
exec "$@"

4、查看执行代码流程

#! /bin/bashCURRENT_DIR=$(pwd)
SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)
TRACE_DIR='/sys/kernel/debug/tracing/'sync
echo 3 > /proc/sys/vm/drop_cachescd ${TRACE_DIR}
echo 0 > ./tracing_on && echo > ./trace
echo $$ > ./set_ftrace_pid # filter pid
echo 1 > ./options/function-forkecho function > ./current_tracer
echo 'bio_add_page:traceon:1' > ./set_ftrace_filter
echo 'blk_update_request:traceoff:1' >> ./set_ftrace_filter
echo 'blk_update_request:stacktrace:1' >> ./set_ftrace_filter
${SCRIPT_DIR}/run_test.sh && cp ./trace ${SCRIPT_DIR}/trace_test.log
echo nop > ./current_tracerecho '!bio_add_page:traceon:count' >> ./set_ftrace_filter
echo '!blk_update_request:traceoff:count' >> ./set_ftrace_filter
echo '!blk_update_request:stacktrace:count' >> ./set_ftrace_filter
echo 0 > ./options/function-fork
echo  > ./set_ftrace_pidcat ${SCRIPT_DIR}/trace_test.log
cd ${CURRENT_DIR}
exec "$@"

5、查看函数执行时间

cat ./available_filter_functions | grep blk_update_request
#!/bin/bashCURRENT_DIR=$(pwd)
SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)
TRACE_DIR='/sys/kernel/debug/tracing/'sync
echo 3 > /proc/sys/vm/drop_cachescd ${TRACE_DIR}
echo bio_add_page > ./set_ftrace_filter
echo vfs_open >> ./set_ftrace_filter
echo 1 > ./options/funcgraph-proc # show process name
echo function_graph > ./current_tracer
echo $$ > ./set_ftrace_pid # filter pid
echo 1 > ./options/function-fork
echo 1 > ./options/pause-on-traceecho function_graph > ./current_tracer # turn on
echo 1 > ./tracing_on
${SCRIPT_DIR}/run_test.sh && cp ./trace ${SCRIPT_DIR}/trace_test.log
echo 0 > ./tracing_on
echo nop > ./current_tracer # turn offecho 0 > ./options/pause-on-trace
echo 0 > ./options/function-fork
echo > ./set_ftrace_pid
echo 0 > ./options/funcgraph-proc
echo '!bio_add_page' >> ./set_ftrace_filter
echo '!vfs_open' >> ./set_ftrace_filtercat ${SCRIPT_DIR}/trace_test.log
cd ${CURRENT_DIR}
exec "$@"

6、查看函数执行时间 和函数向下执行流

cat ./available_filter_functions | grep vfs_open
#!/bin/bashCURRENT_DIR=$(pwd)
SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)
TRACE_DIR='/sys/kernel/debug/tracing/'sync
echo 3 > /proc/sys/vm/drop_cachescd ${TRACE_DIR}
echo vfs_open > ./set_graph_function
echo 1 > ./options/funcgraph-proc # show process name
echo 1 > ./options/funcgraph-tail # add funcgraph tail
echo $$ > ./set_ftrace_pid # filter pid
echo 1 > ./options/function-fork
echo 1 > ./options/pause-on-traceecho function_graph > ./current_tracer # turn on
echo 1 > ./tracing_on
${SCRIPT_DIR}/run_test.sh && cp ./trace ${SCRIPT_DIR}/trace_test.log
echo 0 > ./tracing_on
echo nop > ./current_tracer # turn offecho 0 > ./options/pause-on-trace
echo 0 > ./options/function-fork
echo > ./set_ftrace_pid
echo 0 > ./options/funcgraph-tail
echo 0 > ./options/funcgraph-proc
echo '!vfs_open' >> ./set_graph_functioncat ${SCRIPT_DIR}/trace_test.log
cd ${CURRENT_DIR}
exec "$@"

7、查看函数执行时间 和 函数向下执行流 和函数向上执行流

cat ./available_filter_functions | grep bio_add_page
#!/bin/bashCURRENT_DIR=$(pwd)
SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)
TRACE_DIR='/sys/kernel/debug/tracing/'sync
echo 3 > /proc/sys/vm/drop_cachescd ${TRACE_DIR}
echo 0 > ./tracing_on && echo > ./trace
echo bio_add_page >> ./set_graph_function
echo 1 > ./options/funcgraph-proc # show process name
echo 1 > ./options/funcgraph-tail # add funcgraph tail
echo $$ > ./set_ftrace_pid # filter pid
echo 1 > ./options/function-fork
echo 1 > ./options/pause-on-traceecho 'bio_add_page:stacktrace' > ./set_ftrace_filter
echo function_graph > ./current_tracer # turn on
echo 1 > ./tracing_on
${SCRIPT_DIR}/run_test.sh && cp ./trace ${SCRIPT_DIR}/trace_test.log
echo 0 > ./tracing_on
echo nop > ./current_tracer # turn off
echo '!bio_add_page:stacktrace' > ./set_ftrace_filterecho 0 > ./options/pause-on-trace
echo 0 > ./options/function-fork
echo > ./set_ftrace_pid # filter pid
echo 0 > ./options/funcgraph-tail # add funcgraph tail
echo 0 > ./options/funcgraph-proc # show process name
echo '!bio_add_page' >> ./set_graph_functioncat ${SCRIPT_DIR}/trace_test.log
cd ${CURRENT_DIR}
exec "$@"

8、使用option

在这里插入图片描述

9、使用set_ftrace_filter

在这里插入图片描述

10、使用kprobe

  • 获取磁盘名为例:使用kprobe event对函数bio_add_page进行参数输出

1、数据结构

// dev_name = bio->bi_bdev->bd_disk->disk_name
....

2、数据类型 和 结构体偏移

 # 前置条件:编译内核前选'CONFIG_DEBUG_INFO'的配置项,否则vmlinux会缺少debug符号信息
hinzer@vm:~/lab/linux-trace-lesson$ gdb vmlinux(gdb) whatis bio_add_page
type = int (struct bio *, struct page *, unsigned int, unsigned int)# 方式一: 适用高版本gdb
(gdb) ptype /o struct bio
(gdb) ptype /o struct block_device
(gdb) ptype /o struct gendisk# 方式二: 适用低版本gdb
(gdb) p &((struct bio*)0)->bi_bdev
(gdb) p &((struct block_device*)0)->bd_disk
(gdb) p &((struct gendisk*)0)->disk_name

3、添加和使用kprobe

#!/bin/bashCURRENT_DIR=$(pwd)
SCRIPT_DIR=$(cd $(dirname ${BASH_SOURCE[0]}); pwd)
TRACE_DIR='/sys/kernel/debug/tracing/'cd ${TRACE_DIR}
echo 0 > ./tracing_on && echo > ./trace
echo nop > ./current_tracer# 类比C语言:dev_name = bio->bi_bdev->bd_disk->disk_name
echo 'p bio_add_page dev_name=+0xc(+0x360(+0x8($arg1))):string' > ./kprobe_events
echo 1 > ./events/kprobes/p_bio_add_page_0/enable
echo 1 > ./tracing_on
${SCRIPT_DIR}/run_test.sh && cp ./trace ${SCRIPT_DIR}/trace_test.log
echo 0 > ./tracing_on
echo 0 > ./events/kprobes/p_bio_add_page_0/enable
echo '-:p_bio_add_page_0' >> ./kprobe_eventscat ${SCRIPT_DIR}/trace_test.log
cd ${CURRENT_DIR}
exec "$@"
  • 添加链接描述在这里插入图片描述

4、输出日志

# tracer: nop
#
# entries-in-buffer/entries-written: 24/24   #P:4
#
#                                _-----=> irqs-off
#                               / _----=> need-resched
#                              | / _---=> hardirq/softirq
#                              || / _--=> preempt-depth
#                              ||| /     delay
#           TASK-PID     CPU#  ||||   TIMESTAMP  FUNCTION
#              | |         |   ||||      |         |touch-105     [001] ....  1996.556330: p_bio_add_page_0: (bio_add_page+0x0/0x90) dev_name="vda"kworker/u8:1-59      [002] ....  1996.577168: p_bio_add_page_0: (bio_add_page+0x0/0x90) dev_name="vda"kworker/u8:1-59      [002] ....  1996.577305: p_bio_add_page_0: (bio_add_page+0x0/0x90) dev_name="vda"kworker/u8:1-59      [002] ....  1996.577361: p_bio_add_page_0: (bio_add_page+0x0/0x90) dev_name="vda"jbd2/vda-8-74      [002] ....  1996.579222: p_bio_add_page_0: (bio_add_page+0x0/0x90) dev_name="vda"
http://www.xdnf.cn/news/935677.html

相关文章:

  • LangChain知识库管理后端接口:数据库操作详解—— 构建本地知识库系统的基础《二》
  • AI 大模型统一集成|Spring AI + DeepSeek 实战接入指南
  • 【教学类-53-02】20250607自助餐餐盘教学版(配餐+自助餐)
  • Windows下用CMake编译DCMTK及配置测试
  • DeepSeek R1 V2 深度探索:开源AI编码新利器,效能与创意并进
  • Argo CD 入门 - 安装与第一个应用的声明式同步
  • IDEA为何一直无法使用超过4g内存
  • 文献阅读:Exploring Autoencoder-based Error-bounded Compression for Scientific Data
  • LSTM-SVM多变量时序预测(Matlab完整源码和数据)
  • VB调用CryReport指南方案
  • JVM——对象模型:JVM对象的内部机制和存在方式是怎样的?
  • 【学习笔记】深入理解Java虚拟机学习笔记——第5章 调优案例分析与实战
  • 第12篇:数据库中间件日志设计与追踪系统落地实践
  • MySQL知识回顾总结----数据库基础
  • 计算机常用快捷键分类汇总,涵盖 Windows、macOS 以及通用软件场景
  • STM32[笔记]--1.前置准备
  • AI系统的构建
  • 基于React 的 AntD 库进行前端开发过程中的问题汇总
  • 空间转录组数据下游分析(二)
  • 玄机——某次行业攻防应急响应(带镜像)
  • Java求职者面试指南:计算机基础与源码原理深度解析
  • 智警杯备赛--机器学习算法实践
  • 深度学习登上Nature子刊!特征选择创新思路
  • C# 表达式和运算符(表达式和字面量)
  • 【JavaScript-Day 35】从 window 到 location,一文掌握浏览器对象模型 BOM
  • Web前端开发:JavaScript中的eval()函数
  • triton学习笔记7: GEMM相关
  • uniapp跳转到webview组件的时候,要注意:移除所有不可见字符(包括零宽空格)
  • Linux系统之grub-mkrescue详解
  • vue.js not detected解决方法