可以将linux跟踪系统分成Tracer(跟踪数据来自哪里),数据收集分析(如"ftrace")和跟踪前端(更方便的用户态工具)。

1. 数据源(Tracers)

printk 是一种方法, 但是 printk 终归是毫无选择地全量输出, 某些场景下不实用。

Tracepoint属于静态插装, 是散落在内核源代码中的一些 hook,一旦使能,它们便可以在特定的代码被运行到时被触发。比如Ftrace,Perf就使用了Tracepoint采集数据。

Probe技术属于动态插装(Dynamic Instrument) ,是当内核在运行时动态地修改/插入指令。Kprobes就是这种模式的例子。

1.1 Tracepoint示例–Ftrace function tracer

最早 ftrace 是一个 function tracer, 仅能够记录内核的函数调用流程,Ftrace采用 GCC 的 profile 特性在所有内核函数的开始部分加入一段 stub 代码来实现 function trace 功能。

如今 ftrace 已经成为一个 framework, 采用 plugin 的方式支持开发人员添加更多种类的 trace 功能.这些插件也可能是动态插装。

1.2 Tracepoint示例–Perf tracepoint event

Tracepoint event 是内核中的静态 tracepoint 所触发的事件,这些 tracepoint 用来判断程序运行期间内核的行为细节,比如 slab 分配器的分配次数等。

1.3 Probe示例–Kprobe

简介

kprobe是linux内核的一个重要特性,是一个轻量级的内核调试工具,同时它又是其他一些更高级的内核调试工具(比如systemtap)的"基础设施",4.0版本的内核中,强大的eBPF特性也寄生于kprobe之上,所以kprobe在内核中的地位就可见一斑了。

用法

例如!使用kprobes监视我们的计算机上正在打开哪些文件。

$ sudo ./kprobe 'p:myopen do_sys_open filename=+0(%si):string'

您会注意到kprobes接口本身有点粗糙 - 比如,您必须知道文件名参数do_sys_open是在%si寄存器中并取消引用该指针并告诉kprobes系统它是一个字符串。

kprobes在3种情况下很有用:

  1. 您正在跟踪系统调用。系统调用都具有相应的内核函数,例如do_sys_open
  2. 您正在调试网络堆栈中的某些性能问题或者处理文件I / O,并且您了解内核函数,这些函数被调用得足以让您跟踪它们
  3. 你是一个内核开发人员,或者你正试图调试内核bug,有时会发生!

原理

基本上kprobes允许您在运行时动态更改Linux内核的汇编代码(比如,插入额外的汇编指令)以跟踪调用给定指令的时间。

内核源码下有目录下sample/kprobes,该目录下有许多kprobes的例子,可以仿照这些例子写自己的kprobe模块。

以kprobe_example.c为例:

首先 声明一个kprobe结构体,然后定义其中几个关键成员变量,包括symbol_name,pre_handler,post_handler。其中,symbol_name是函数名(kprobe_example.c中该项为do_fork),告诉内核我的探测点放置在了函数do_fork处,pre_handler和post_handler分别表示在执行探测点之前和之后执行的钩子函数。

然后 通过register_kprobe函数注册kprobe即可。

2. 数据收集和分析

2.1 Ftrace

原理

ftrace使用–debugfs

ftrace 通过 debugfs 向用户态提供访问接口。配置内核时激活 debugfs 后会创建目录 /sys/kernel/debug ,debugfs 文件系统就是挂载到该目录。

mount -t debugfs nodev /sys/kernel/debug

激活内核对 ftrace 的支持后会在 debugfs 下创建一个 tracing 目录 /sys/kernel/debug/tracing 。该目录下包含了 ftrace 的控制和输出文件。

使用示例:

  1. cd /sys/kernel/debug/tracing
  2. echo function > current_tracer
  3. echo do_page_fault > set_ftrace_filter
  4. cat trace

内核配置编译

通常在配置内核时,使用 make menuconfig 会更直观一些。要将 ftrace 编译进内核,可以选中 Kernel hacking下的 Tracers 菜单项。

ftrace 通过 debugfs 向用户态提供了访问接口,所以还需要将 debugfs 编译进内核。激活对 debugfs 的支持,可以直接编辑内核配置文件 .config ,设置 CONFIG_DEBUG_FS=y ;或者在 make menuconfig 时到 Kernel hacking 菜单下选中对 debugfs 文件系统的支持。

配置完成后,编译安装新内核,然后启动到新内核。 注意,激活 ftrace 支持后,编译内核时会使用编译器的 -pg 选项,这是在 kernel/trace/Makefile 文件中定义的。

ftrace跟踪器

ftrace 当前包含多个跟踪器,用于跟踪不同类型的信息,比如进程调度、中断关闭等。可以查看文件 available_tracers 获取内核当前支持的跟踪器列表。在编译内核时,也可以看到内核支持的跟踪器对应的选项。

nop跟踪器 不会跟踪任何内核活动,将 nop 写入 current_tracer 文件可以删除之前所使用的跟踪器,并清空之前收集到的跟踪信息,即刷新 trace 文件。

function跟踪器 可以跟踪内核函数的执行情况;可以通过文件 set_ftrace_filter 显示指定要跟踪的函数。

function_graph跟踪器 可以显示类似 C 源码的函数调用关系图,这样查看起来比较直观一些;可以通过文件 set_grapch_function 显示指定要生成调用流程图的函数。

sched_switch跟踪器 可以对内核中的进程调度活动进行跟踪。

irqsoff跟踪器和 preemptoff跟踪器 分别跟踪关闭中断的代码和禁止进程抢占的代码,并记录关闭的最大时长,preemptirqsoff跟踪器则可以看做它们的组合。

ftrace 还支持其它一些跟踪器,比如 initcall、ksym_tracer、mmiotrace、sysprof 等。ftrace 框架支持扩展添加新的跟踪器。读者可以参考内核源码包中 Documentation/trace 目录下的文档以及 kernel/trace 下的源文件,以了解其它跟踪器的用途和如何添加新的跟踪器。

2.2 SystemTap

SystemTap的框架允许用户开发简单的脚本,用于调查和监视内核空间中发生的各种内核函数,系统调用和其他事件。它是一个允许用户开发自己的特定于内核的取证和监视工具的系统。

原理


Systemtap基于Kprobe实现。

  • 工作原理是通过将脚本语句翻译成C语句,编译成内核模块。
  • 模块加载之后,将所有探测的事件以钩子的方式挂到内核上,当任何处理器上的某个事件发生时,相应钩子上句柄就会被执行。
  • 最后,当systemtap会话结束之后,钩子从内核上取下,移除模块。

整个过程用一个命令 stap 就可以完成。

安装使用

  1. 编译内核以支持systemtap

我们重新编译内核让其支持systemtap,首先你想让内核中有调试信息,编译内核时需要加上 -g 标志;其次,你还需要在配置内核时将 Kprobe 和 debugfs 开关打开。最终效果是,你能在内核 .config 文件中看到下面四个选项是设置的:

CONFIG_DEBUG_INFO

CONFIG_KPROBES

CONFIG_DEBUG_FS

CONFIG_RELAY

  1. 获取systemtap源码

  2. 编译安装systemtap

2.3 Perf

Perf 是用来进行软件性能分析的工具。

通过它, 应用程序可以利用 PMU, tracepoint 和内核中的特殊计数器来进行性能统计. 它不但可以分析指定应用程序的性能问题 (per thread). 也可以用来分析内核的性能问题, 当然也可以同时分析应用代码和内核,从而全面理解应用程序中的性能瓶颈.

使用示例

perf stat, perf stat -e raw_syscalls:sys_enter ls

perf top

perf record, perf record -e cpu-clock ./t1

3. 前端显示

Trace-cmd

trace-cmd是ftrace的前端,您可以使用它来收集和显示ftrace数据。

火焰图(flame graph)

可以使用Linux perf_events,FreeBSD pmcstat(hwpmc),DTrace,SystemTap和许多其他分析器捕获堆栈样本。

3. eBPF

参考

Linux内核调试的方式以及工具集锦

动态追踪技术漫谈

Linux内核调试原理和工具介绍--理解静态插装/动态插装、tracepoint、ftrace、kprobe、SystemTap、Perf、eBPF相关推荐

  1. Linux内核调试的方式以及工具集锦

    Linux内核调试的方式以及工具集锦 CSDN GitHub Linux内核调试的方式以及工具集锦 LDD-LinuxDeviceDrivers/study/debug  本作品采用知识共享署名-非商 ...

  2. 【转载】ubuntu下linux内核源码阅读工具和调试方法总结

    http://blog.chinaunix.net/space.php?uid=20940095&do=blog&cuid=2377369 一 linux内核源码阅读工具 window ...

  3. Linux内核调试方法总结【转】

    转自:http://my.oschina.net/fgq611/blog/113249 内核开发比用户空间开发更难的一个因素就是内核调试艰难.内核错误往往会导致系统宕机,很难保留出错时的现场.调试内核 ...

  4. Linux内核调试方法总结

    [转]Linux内核调试方法总结 目录[-] 一  调试前的准备 二  内核中的bug 三  内核调试配置选项 1  内核配置 2  调试原子操作 四  引发bug并打印信息 1  BUG()和BUG ...

  5. linux内核调试指南

    Hunnad的专栏 * 条新通知 * 登录 * 注册 * 欢迎 * 退出 * 我的博客 * 配置 * 写文章 * 文章管理 * 博客首页 * * * * 空间 * 博客 * 好友 * 相册 * 留言 ...

  6. Linux Kernel - Debug Guide (Linux内核调试指南 )

    linux内核调试指南 一些前言 作者前言 知识从哪里来 为什么撰写本文档 为什么需要汇编级调试 ***第一部分:基础知识*** 总纲:内核世界的陷阱 源码阅读的陷阱 代码调试的陷阱 原理理解的陷阱 ...

  7. Linux内核调试方法【转】

    转自:http://www.cnblogs.com/shineshqw/articles/2359114.html kdb:只能在汇编代码级进行调试: 优点是不需要两台机器进行调试. gdb:在调试模 ...

  8. 开源项目-基于Intel VT技术的Linux内核调试器

    本开源项目将硬件虚拟化技术应用在内核调试器上,使内核调试器成为VMM,将操作系统置于虚拟机中运行,即操作系统成为GuestOS,以这样的一种形式进行调试,最主要的好处就是调试器对操作系统完全透明.如下 ...

  9. Linux内核调试技术指南

    前两天,完成了ucos在2440上的移植,以及boot的修改.今天突然想到,我在linux下,该如何来编写,调试比较复杂的驱动.我想这个问题应该从如何调试内核入手,先转载两个文字,待西西看来. 系统搭 ...

最新文章

  1. request.getParameterMap()的坑
  2. SD-WAN — 核心能力
  3. Android笔记一.深入理解Intent和IntentFilters(一)
  4. 原码, 反码, 补码, 移码 详解
  5. 制作自己的Puppy Linux Live-CD发行版的三种方法
  6. 5.3矩阵乘积(三元组存储结构)
  7. C++ 冒泡算法 练习
  8. C# 置顶EXE 把EXE放最前面 ProcessStartInfo
  9. GIMP基本功能和教程!
  10. 精灵五笔 优化指南【原】
  11. ABB机器人仿真软件RobotSdutio 安装使用常见部分问题集
  12. linux卡片电脑设计,ThinkPad重大更新!5款创意设计PC齐发2日
  13. 希腊呼吁欧委会增加欧洲网络与信息安全管理局预算
  14. 心中无码便是高清,用“脑补”除马赛克!
  15. 怎么选最快dns服务器,dns设置(dns设置哪个最好最快)
  16. lwip---(五)以太网数据接收
  17. 2021-02-09
  18. 使用conda安装pytorch时出现问题CondaSSLError: OpenSSL appears to be unavailable on this machine.
  19. 关于tensor的shape理解
  20. vue3中导出excel表格

热门文章

  1. 如何连接文档服务器,如何连接服务器地址
  2. 关于泰勒展开的两点思考
  3. java中的ackerman_java8的函数式接口
  4. python输出输入的指定位数的密码_用python生成指定位数的密码
  5. android 9.0 权限管理_你真的了解Android权限机制吗?
  6. SpringBoot项目集成Mybatis Plus(五)条件构造器
  7. oracle外关联更新操作,记要oracle 关联更新的例子
  8. python解析pdf得到每个字符的坐标
  9. java中什么是底层数据结构_JavaScript 对象的底层数据结构是什么
  10. java nio底层实现_Java NIO 底层原理