使用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读取追踪文件并展示结果,帮助分析每个事件的时间、持续时长及涉及的进程等信息,从而深入了解内核行为,无论是日常调试还是性能优化都能得心应手。

相关推荐
ICscholar18 小时前
ExaDigiT/RAPS
linux·服务器·ubuntu·系统架构·运维开发
sim202018 小时前
systemctl isolate graphical.target命令不能随便敲
linux·mysql
薛定谔的猫198219 小时前
RAG(二)基于 LangChain+FAISS + 通义千问搭建轻量级 RAG 检索增强生成系统
运维·服务器·langchain
米高梅狮子19 小时前
4. Linux 进程调度管理
linux·运维·服务器
再创世纪20 小时前
让USB打印机变网络打印机,秀才USB打印服务器
linux·运维·网络
fengyehongWorld21 小时前
Linux ssh端口转发
linux·ssh
昨夜见军贴061621 小时前
IACheck AI审核如何实现自动化来料证书报告审核,全面提升生产效率与合规水平
运维·人工智能·自动化
知识分享小能手1 天前
Ubuntu入门学习教程,从入门到精通, Ubuntu 22.04中的Shell编程详细知识点(含案例代码)(17)
linux·学习·ubuntu
浩子智控1 天前
电子产品设计企业知识管理
运维·服务器·eclipse·系统安全·硬件工程
Xの哲學1 天前
深入解析 Linux systemd: 现代初始化系统的设计与实现
linux·服务器·网络·算法·边缘计算