1 前言

本文为 Ftrace 系列文章第二篇,描述 Ftrace 进阶用法。上一篇文章中我们接触到了 Ftrace 基本概念,知道了如何 trace 一个函数,知道了如何 enable 一个 trace event。

同时,上一篇文章也遗留了几个问题:

  • 如何跟踪某个进程?如何跟踪一个命令,但是这个命令执行时间很短?
  • 用户态的行为轨迹如何与内核中的 trace 联系到一起?
  • 如何跟踪过滤多个进程?多个函数?
  • 如何灵活控制 trace 的开关?

本文将一一解答上述问题。

2 查看函数调用栈

查看函数调用栈是内核调试最最基本得需求,常用方法:

  • 函数内部添加 WARN_ON(1)
  • ftrace

trace 函数的时候,设置 echo 1 > options/func_stack_trace 即可在 trace 结果中获取追踪函数的调用栈。

以 dev_attr_show 函数为例,看看 ftrace 如何帮我们获取调用栈:

$ cd /sys/kernel/debug/tracing
$ sudo -s
# echo 0 > tracing_on
# echo function > current_tracer
# echo dev_attr_show > set_ftrace_filter
// 设置 func_stack_trace
# echo 1 > options/func_stack_trace
# echo 1 > tracing_on
# cat trace
# tracer: function
#
# entries-in-buffer/entries-written: 8/8 #P:4
#
# _-----=> irqs-off
# / _----=> need-resched
# | / _---=> hardirq/softirq
# || / _--=> preempt-depth
# ||| / delay
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
# | | | |||| | |
top-3008 [003] .... 621.507777: dev_attr_show <-sysfs_kf_seq_show
top-3008 [003] .... 621.507784: <stack trace>
=> dev_attr_show
=> sysfs_kf_seq_show
=> kernfs_seq_show
=> seq_read
=> kernfs_fop_read
=> __vfs_read
=> vfs_read
=> ksys_read
=> __x64_sys_read
=> do_syscall_64
=> entry_SYSCALL_64_after_hwframe
=> 0
=> 0
=> 0
=> 0
=> 0
=> 0
=> 0
=> 0

3 如何跟踪一个命令,但是这个命令执行时间很短?

首先我们介绍一下 ftrace 过滤控制相关文件:

文件名 功能
set_ftrace_filter function tracer 只跟踪某个函数
set_ftrace_notrace function tracer 不跟踪某个函数
set_graph_function function_graph tracer 只跟踪某个函数
set_graph_notrace function_graph tracer 不跟踪某个函数
set_event_pid trace event 只跟踪某个进程
set_ftrace_pid function/function_graph tracer 只跟踪某个进程

如果这时候问:如何跟踪某个进程内核态的某个函数?

答案是肯定的,将被跟踪进程的 pid 设置到 set_event_pid/set_ftrace_pid 文件即可。

但是如果问题变成了,我要调试 kill 的内核执行流程,如何办呢?

因为 kill 运行时间很短,我们不能知道它的 pid,所以就没法过滤了。

调试这种问题的小技巧,即 脚本化,这个技巧在很多地方用到:

sh -c "echo $$ > set_ftrace_pid; echo 1 > tracing_on; kill xxx; echo 0 > tracing_on"

PS:请在这里面加上你需要过滤的函数或其它设置

4 过滤技巧 - 如何跟踪过滤多个进程?多个函数?

4.1 情景1:函数名雷同,可以使用正则匹配

# cd /sys/kernel/debug/tracing
# echo 'dev_attr_*' > set_ftrace_filter
# cat set_ftrace_filter
dev_attr_store
dev_attr_show

4.2 情景2:追加某个函数

用法为:echo xxx >> set_ftrace_filter,例如,先设置 dev_attr_*

# cd /sys/kernel/debug/tracing
# echo 'dev_attr_*' > set_ftrace_filter
# cat set_ftrace_filter
dev_attr_store
dev_attr_show

再将 ip_rcv 追加到跟踪函数中:

# cd /sys/kernel/debug/tracing
# echo ip_rcv >> set_ftrace_filter
# cat set_ftrace_filter
dev_attr_store
dev_attr_show
ip_rcv

4.3 情景3:基于模块过滤

格式为:<function>:<command>:<parameter>,例如,过滤 ext3 module 的 write* 函数:

$ echo 'write*:mod:ext3' > set_ftrace_filter

4.4 情景4:从过滤列表中删除某个函数,使用“感叹号”

格式为:<function>:<command>:<parameter>,例如,过滤 ext3 module 的 write* 函数:

$ echo 'write*:mod:ext3' > set_ftrace_filter

4.4 情景4:从过滤列表中删除某个函数,使用“感叹号”

感叹号用来移除某个函数,把上面追加的 ip_rcv 去掉:

# cd /sys/kernel/debug/tracing
# cat set_ftrace_filter
dev_attr_store
dev_attr_show
ip_rcv
# echo '!ip_rcv' >> set_ftrace_filter
# cat set_ftrace_filter
dev_attr_store
dev_attr_show

PS:上述所有涉及通配符的操作最好都加上单引号。

5 用户态内核态联动

有些问题是需要将用户态、内核态的行为联系在一起的,但是 printf/printk 天然是分家的,如何办?

答案是 trace_marker,用户态程序只需要打开 trace_marker 节点可以向其中写入内容,写入的内容会体现在 trace 文件中,与内核态的各种 trace 融合在一起,提供时间线、事件参考

# cd /sys/kernel/debug/tracing
# echo 'hello ftrace' > trace_marker
# cat trace
# tracer: nop
#
# entries-in-buffer/entries-written: 1/1 #P:4
#
# _-----=> irqs-off
# / _----=> need-resched
# | / _---=> hardirq/softirq
# || / _--=> preempt-depth
# ||| / delay
# TASK-PID CPU# |||| TIMESTAMP FUNCTION
# | | | |||| | |
<...>-2157 [001] .... 1227.772963: tracing_mark_write: hello ftrace

6 灵活控制 trace 开关

6.1 用户态

用户态程序可以很灵活的控制 trace 开关,因为可以在程序中打开 tracing_on 文件,灵活控制何时 enable,何时 disable。

6.2 内核态

如何在跟踪内核函数的时候灵活控制 trace enable/disable 呢?

首先明确这件事的意义:根据条件及时停止,更准确获取现场信息,同时防止后面的无效信息冲掉有效信息。

这种功能是通过 set_ftrace_filter 实现的,控制范式:<function>:<command>:<parameter>

简单示例:遇到 __schedule_bug 函数后关闭 trace

# echo '__schedule_bug:traceoff' > set_ftrace_filter

除了 traceoff 外,set_ftrace_filter 还支持其它的关键字,感兴趣的请阅读:filter-commands

7 前端工具

Ftrace 提供了 trace 能力,但是使用起来还是有点麻烦,所以有一些前端工具,一来方便大家使用,比如 trace-cmd,二来将许多调试能力大一统,比如 perf/bcc。

Ftrace 进阶用法的更多相关文章

  1. Django框架学习-Model进阶用法

    Model进阶用法 回顾 访问外键 访问多对多关系 更改数据库结构 当处理数据库结构改变时,需要注意到几点: 增加字段 首先在开发环境中: 再到产品环境中: 删除字段 删除多对多字段 删除model ...

  2. canvas图形处理和进阶用法

    前面的话 上一篇博客介绍了canvas基础用法,本文将更进一步,介绍canvas的图形处理和进阶用法 图形变换 图形变换是指用数学方法调整所绘形状的物理属性,其实质是坐标变形.所有的变换都依赖于后台的 ...

  3. 前端自动化测试神器-Katalon进阶用法

    前言 上一篇介绍了Katalon的基础用法,本篇继续介绍一些进阶的用法. Keyword 和 Method Call Statement Keyword Keyword就是自定义方法,该方法在当前项目 ...

  4. SpringBoot进阶用法-随笔

    SpringBoot进阶用法 实现setApplicationContext //实现ApplicationContextAware接口,重写setApplicationContext方法 publi ...

  5. CocoaPods学习系列4——进阶用法

    这篇文章,记录一下CocoaPods的进阶用法. 进阶用法主要体现在.podspec文件和Podfile的配置上. .podspec文件的进阶配置 以官方的一个.podspec文件示例细说: Pod: ...

  6. (数据科学学习手札61)xpath进阶用法

    一.简介 xpath作为对网页.对xml文件进行定位的工具,速度快,语法简洁明了,在网络爬虫解析内容的过程中起到很大的作用,除了xpath的基础用法之外(可参考我之前写的(数据科学学习手札50)基于P ...

  7. webpack进阶用法你都get到了么?

    如何消除无用代码:打包自己的私有js库:实现代码分割和动态import提升初次加载速度:配置eslint规范团队代码规范:打包异常抓捕你都get到了么? 摇树优化:Tree Shaking webpa ...

  8. xpath进阶用法

    一.简介 xpath作为对网页.对xml文件进行定位的工具,速度快,语法简洁明了,在网络爬虫解析内容的过程中起到很大的作用,除了xpath的基础用法之外xpath中还存在着非常之多的进阶用法,本文将对 ...

  9. ASP.NET Core 6框架揭秘实例演示[14]:日志的进阶用法

    为了对各种日志框架进行整合,微软创建了一个用来提供统一的日志编程模式的日志框架.<日志的基本编程模式>以实例演示的方式介绍了日志的基本编程模式,现在我们来补充几种"进阶" ...

  10. Spring Data JPA系列3:JPA项目中核心场景与进阶用法介绍

    大家好,又见面了. 到这里呢,已经是本SpringData JPA系列文档的第三篇了,先来回顾下前面两篇: 在第1篇<Spring Data JPA系列1:JDBC.ORM.JPA.Spring ...

随机推荐

  1. 《Programming from the Ground Up》阅读笔记:p88-p94

    <Programming from the Ground Up>学习第5天,p88-p94总结,总计7页. 一.技术总结 1.touppercase.s #PURPOSE: This pr ...

  2. 免费使用TasteWP一键搭建线上临时WordPress网站

    虽然用宝塔面板或者1Panel面板可以非常快速的搭建一个WordPress网站,但是有时候只想测试下我设计的页面或者开发的主题和插件,又得买服务器,绑定域名,安装程序,搭建起来也过于浪费时间了:再或者 ...

  3. 第零讲:基础架构:一条SQL查询语句是如何执行的

    目录 第零讲:基础架构:一条SQL查询语句是如何执行的 正确的认识事物的方式方法(极为重要): sql语句内部的执行过程:(极为重要) MySQL 可以分为 Server 层和存储引擎层两部分. Se ...

  4. 【DataBase】MySQL 09 SQL函数 单行函数其三 日期函数

    日期函数 日期&时间函数 NOW 当前日期时间. CURDATE 当前日期. CURTIME 当前时间 -- NOW();返回系统日期+时间 SELECT NOW(); -- CURDATE( ...

  5. 【SpringBoot】16 数据访问P4 整合JPA

    DAO面向SpringData操作 Spring Data 项目的目的是为了简化构建基于 Spring 框架应用的数据访问技术, 包括非关系数据库.Map-Reduce 框架.云数据服务等等: 另外也 ...

  6. tmux开启鼠标模式

    在tmux的配置文件中进行配置: vim ~/.tmux.conf set -g mouse on

  7. 在使用pytorch官方给出的torchvision中的预训练模型参数时为保证收敛性要求使用原始的数据预处理方式

    本文主要内容如题: 在使用pytorch官方给出的torchvision中的预训练模型参数时为保证收敛性要求使用原始的数据预处理方式 具体的pytorch官方讨论: https://github.co ...

  8. awk批量提取序列

    在提取前需保证序列文件仅有一列! awk '{print$1}' input.fa > ouput.fa#就可将ID后面的其余注释信息去掉,仅保留ID 1 awk -F '>' 'NR=F ...

  9. QT的基础设置(菜单栏、状态栏、任务栏。。。。)

    Qt [1] 是一个1991年由Qt Company开发的跨平台C++图形用户界面应用程序开发框架.它既可以开发GUI程序,也可用于开发非GUI程序,比如控制台工具和服务器.下面介绍QT的基础配置 1 ...

  10. 牛客周赛 Round 5

    牛客周赛 Round 5 A-游游的字母变换_牛客周赛 Round 5 (nowcoder.com) #include <bits/stdc++.h> #define int long l ...