使用trace-cmd跟踪Linux内核函数:一次愉快的内核探险

使用trace-cmd跟踪Linux内核函数:一次愉快的内核探险

1. 第一次亲密接触trace-cmdftrace

1.1 ftrace: 内核的秘密侦探

想象一下,如果你能有一个工具,它像一个隐身的侦探一样,在你不打扰它的日常工作的情况下,悄悄地告诉你内核里都在发生什么。这就是ftrace!它是Linux内核自带的一个跟踪利器,专门用来窥探内核内部的世界。通过ftrace,你可以看到函数是如何调用的,了解各种事件的发生,甚至还能找到性能瓶颈。简单来说,ftrace就像是内核的"心灵捕手",帮你理解它的内心世界。

1.2 trace-cmd: 让侦探工作变得更简单

现在,假设我们的侦探(ftrace)虽然很厉害,但是有时候报告有点复杂,不容易看懂。这时候就需要一个好助手了------trace-cmd登场!这个用户态工具就是为了让ftrace的使用更加直观、便捷而设计的。它就像给侦探配了一个翻译机,把复杂的内核语言转换成我们容易理解的话。有了trace-cmd,启动跟踪、查看数据都变得轻而易举。

1.3 trace-cmdftrace: 组合出击

说到关系,trace-cmd就好比是ftrace的私人助理。它简化了配置过程,并且让输出的数据更容易消化,这样开发者就不用直接去捣鼓那些神秘的/sys/kernel/debug文件了。这种组合就像是拥有了一套高级音响系统,其中ftrace是主机,而trace-cmd则是遥控器,让你可以轻松控制一切。

2. trace-cmd基本语法

2.1 可以跟踪什么: trace-cmd list

想要知道你的侦探工具(trace-cmd)能帮你找到什么样的线索吗?使用trace-cmd list命令,你可以列出所有可用的事件源和可以监控的内核函数。这就像在探险之前先查看地图,了解哪些地方值得探索。通过这个命令,你能看到系统中所有的可追踪事件、函数以及它们所属的子系统。

常用参数和示例:

  • -t:列出当前系统上启用的所有追踪器(tracers)。追踪器不仅仅是简单的记录事件,它们通常会提供特定类型的追踪功能或模式。例如,function_graph追踪器可以展示函数调用的层级关系。

    bash 复制代码
    trace-cmd list -t
    # 输出示例:
    timerlat osnoise hwlat blk mmiotrace function_graph wakeup_dl wakeup_rt wakeup function nop

    最常用的就是functionfunction_graph ,下文会演示他们的作用。

  • -s:列出所有可用的事件分类。每个事件分类代表一个内核子系统的事件集合。这些事件都是内核代码里预定义好的;而function跟踪器这可以跟踪任意的内核函数。当然这些预定义的事件输出的信息更详细一点。

  • -e [regex]:列出当前系统上启用的所有事件分类中的详细事件,或者根据正则表达式regex过滤特定的事件。如果你只对网络相关的事件感兴趣,可以这样做:

    bash 复制代码
    trace-cmd list -e net:
    # 输出示例:
    net:netif_receive_skb_list_exit
    net:netif_rx_exit
    net:netif_receive_skb_exit
    ...
  • -f [regex]:列出所有可用于过滤的函数。这些是系统中你能够追踪或作为过滤条件的函数。你可以通过正则表达式来筛选特定前缀的函数,比如所有以vfs_开头的文件系统操作相关函数:

    bash 复制代码
    trace-cmd list -f ^vfs_
    # 输出示例:
    vfs_fadvise
    vfs_fallocate
    vfs_truncate
    ...

通过上述命令及其参数,你可以详细查看trace-cmd可以监控哪些东西。

2.2 开始跟踪: trace-cmd record

当你已经选定了要跟踪的目标后,就可以启动追踪了!trace-cmd record就是你用来"部署"侦探到现场的命令。它可以记录内核活动,并将数据保存到一个文件中供后续分析。这里有几个常用的选项可以帮助你更精确地控制追踪过程:

  • -p tracer:指定一个追踪器。常见的追踪器包括function(用于追踪函数调用)、function_graph(用于绘制函数调用图),以及其他如preemptirqsoffirqsoff等。要查看可用的追踪器列表,请参见trace-cmd list -t

  • -e event:指定要追踪的事件。各种静态跟踪点已经被添加到Linux内核中,它们按照子系统分组,你可以启用整个子系统的事件或指定具体的事件。事件格式为"subsystem:event-name"。例如,"-e sched_switch"会启用sched_switch事件,而"-e sched"则会启用sched子系统下的所有事件。

  • -l function-name:限制functionfunction_graph追踪器仅追踪给定的函数名。支持完整的正则表达式解析或基本的通配符匹配。如果过滤器仅包含字母数字、下划线、星号、问号和句点,则会被视为基本通配符;若要强制解析为正则表达式,可以在过滤器前加上^或在后面加上$。

  • -g function-name:对于function_graph插件,该选项会创建给定函数的调用图,即只追踪该函数及其直接或间接调用的所有其他函数。

举个例子,如果你想追踪所有的内核函数调用,可以这样执行:

bash 复制代码
sudo trace-cmd record -p function

而如果你只想追踪某个特定函数,比如sys_open,则可以这样做:

bash 复制代码
sudo trace-cmd record -p function -l sys_open

2.3 查看跟踪报告: trace-cmd report

完成了追踪之后,最重要的一步就是解读收集到的数据。这就是trace-cmd report发挥作用的地方------它能够读取由record命令生成的追踪文件,并以易于理解的方式展示出来。你可以从这些报告中了解到每个事件的发生时间、持续多久、涉及哪些进程等重要信息。

为了查看最近一次的追踪结果,只需简单地运行:

bash 复制代码
sudo trace-cmd report

此外,report命令还支持多种格式化选项,允许你根据需要调整输出内容,比如按时间排序、显示CPU编号等。这使得数据分析更加直观和高效。通过结合trace-cmd listtrace-cmd recordtrace-cmd report这三个基本命令,你可以深入探究Linux内核的行为,无论是日常调试还是性能优化都能得心应手。

3. trace-cmd使用示例

为了让您更好地理解如何使用trace-cmd,我们举一些常用的例子。通过这些示例,您可以学习到如何设置追踪、捕捉特定的内核活动以及如何分析生成的数据。

3.1 跟踪事件源

  • 使用 trace-cmd list -s 查看所有可以监控的事件源
3.1.1 监控网络事件: -e net

要监控与网络相关的事件,你可以使用-e选项指定你感兴趣的事件类型。例如,如果你想查看所有与网络子系统相关的事件,可以这样做:

bash 复制代码
sudo trace-cmd record -e net -F ping www.baidu.com -c1

这条命令会启动对所有网络相关事件的追踪,并且只记录由ping命令(发送一个ICMP请求)触发的活动。执行完上述命令后,运行ping命令,完成后按Ctrl+C停止追踪。然后使用trace-cmd report来查看和分析结果。

3.1.2 跟踪调度器行为

如果你想探究Linux调度器的行为,可以使用sched_switch事件来追踪进程之间的切换:

bash 复制代码
# 开始追踪sched_switch事件
sudo trace-cmd record -e sched:sched_switch sleep 3

这个命令开始追踪调度器事件,并等待3秒后自动结束追踪。这段时间内发生的任何进程间的切换都会被记录下来。之后,你可以使用trace-cmd report来检查哪个进程在何时被调度了。

3.1.3 跟踪所有系统调用

如果你想要全面监控系统的每一个系统调用,包括它们的参数和返回值,可以使用sys_entersys_exit事件。这对于深入了解应用程序与操作系统之间的交互非常有用,尤其是在调试或性能分析时。通过这种方式,你可以捕捉到每个系统调用的进入(sys_enter)和退出(sys_exit)时刻,并查看其传递给内核的参数以及从内核返回的结果。

例如,假设你想追踪执行ls命令期间的所有系统调用活动,可以使用以下命令:

bash 复制代码
sudo trace-cmd record -e syscalls:sys_enter_* -e syscalls:sys_exit_* -F ls

这条命令的具体含义如下:

  • -e syscalls:sys_enter_*:启用所有系统调用进入事件的追踪。
  • -e syscalls:sys_exit_*:启用所有系统调用退出事件的追踪。
  • -F ls:指定只记录由ls命令触发的系统调用活动。

3.2 跟踪具体函数

有时候你需要知道某个特定的系统调用是如何被执行的,比如打开文件(sys_open)。可以通过过滤函数名来进行追踪:

bash 复制代码
# 开始追踪sys_open及其相关函数调用
sudo trace-cmd record -p function -l *open* -F cat /etc/passwd

这段命令将启动一个函数追踪器,专门针对名字中包含open的所有函数,同时仅记录由cat命令触发的活动。这可以帮助你了解当读取文件时,内核内部发生了哪些函数调用。完成操作后,使用trace-cmd report来查看详细的函数调用列表。

3.3 跟踪函数调用图

假设你想要深入了解文件系统中的vfs_open函数是如何工作的,包括它调用了哪些其他函数。你可以使用function_graph追踪器来创建一个调用图,这将帮助你看到vfs_open及其所有子函数的执行流程。为了确保只跟踪由特定命令(如cat)引发的函数调用,可以结合-g-F选项:

bash 复制代码
# 开始追踪vfs_open函数调用图
sudo trace-cmd record -p function_graph -g vfs_open -F cat /etc/passwd

这条命令的意思是:启动function_graph追踪器,专门追踪vfs_open函数及其调用链,并且只记录由cat命令触发的活动。之后你可以使用trace-cmd report查看详细的调用图。从报告中可以看到每个函数的调用时间、持续时间和调用层次结构,这对调试和性能分析非常有用。

4. 总结

trace-cmd结合内核自带的ftrace工具,为Linux内核提供了强大的跟踪功能。ftrace作为内置的跟踪机制,能悄无声息地揭示内核内部运作细节,如函数调用流程和事件发生情况。而trace-cmd则是一个用户空间工具,旨在简化ftrace的使用,使启动跟踪、查看数据变得简单直观。

通过trace-cmd list命令,用户可以列出所有可用的事件源、追踪器、事件以及可过滤的函数,这有助于规划追踪策略。trace-cmd record用于启动追踪并记录内核活动到文件中,支持指定追踪器、事件或特定函数等选项,以便更精确地控制追踪过程。最后,trace-cmd report读取追踪文件并展示结果,帮助分析每个事件的时间、持续时长及涉及的进程等信息,从而深入了解内核行为,无论是日常调试还是性能优化都能得心应手。

相关推荐
海绵波波1077 分钟前
zerotier实现内网穿透(访问内网服务器)
运维·服务器
helpme流水12 分钟前
使用秘钥登录服务器
运维·服务器·github
ccino .14 分钟前
【实现多网卡电脑的网络连接共享】
运维·服务器
稳联技术34 分钟前
科技潮头浪接天,一桥飞架两界连。EthernetIP转Profinet互译连
linux·服务器·网络
阿moments37 分钟前
Docker - 速成
运维·docker·云原生·容器
落寞书生1 小时前
docker安装mysql 实现主从同步
运维·mysql·docker·主从同步·docker 安装mysql
人类群星闪耀时2 小时前
机器学习在自动化运维中的应用:提升运维效率的新利器
运维·机器学习·自动化
明金同学3 小时前
腾讯云海外服务器Window切换为linux系统(从Window DD 到 Linux)
linux·服务器·腾讯云
CC大煊4 小时前
【Linux】vi/vim 使用技巧
linux·运维·vim
是十一月末4 小时前
Linux的基本功能和命令
linux·服务器·开发语言·数据库