1 内核调试以及工具总结
内核总是那么捉摸不透, 内核也会犯错, 但是调试却不能像用户空间程序那样, 为此内核开发者为我们提供了一系列的工具和系统来支持内核的调试.
内核的调试, 其本质是内核空间与用户空间的数据交换, 内核开发者们提供了多样的形式来完成这一功能.
2 用户空间与内核空间数据交换的文件系统
内核中有三个常用的伪文件系统: procfs, debugfs和sysfs.
它们都用于Linux内核和用户空间的数据交换, 但是适用的场景有所差异:
procfs
历史最早, 最初就是用来跟内核交互的唯一方式, 用来获取处理器、内存、设备驱动、进程等各种信息.sysfs
跟kobject
框架紧密联系, 而kobject
是为设备驱动模型而存在的, 所以sysfs
是为设备驱动服务的.debugfs
从名字来看就是为debug
而生, 所以更加灵活.relayfs
是一个快速的转发(relay)
数据的文件系统, 它以其功能而得名. 它为那些需要从内核空间转发大量数据到用户空间的工具和应用提供了快速有效的转发机制.
相关资料链接:
在 Linux 下用户空间与内核空间数据交换的方式, 第 2 部分: procfs、seq_file、debugfs和relayfs:http://www.ibm.com/developerworks/cn/linux/l-kerns-usrs2/
Linux 文件系统:procfs, sysfs, debugfs 用法简介:http://www.tinylab.org/show-the-usage-of-procfs-sysfs-debugfs/
2.1 procfs文件系统
ProcFs
介绍
procfs
是比较老的一种用户态与内核态的数据交换方式, 内核的很多数据都是通过这种方式出口给用户的, 内核的很多参数也是通过这种方式来让用户方便设置的. 除了 sysctl
出口到 /proc
下的参数, procfs
提供的大部分内核参数是只读的. 实际上, 很多应用严重地依赖于procfs, 因此它几乎是必不可少的组件. 前面部分的几个例子实际上已经使用它来出口内核数据, 但是并没有讲解如何使用, 本节将讲解如何使用procfs
.
-
参考资料:
用户空间与内核空间数据交换的方式(2)——procfs:http://www.cnblogs.com/hoys/archive/2011/04/10/2011141.html
2.2 sysfs文件系统
内核子系统或设备驱动可以直接编译到内核, 也可以编译成模块, 编译到内核, 使用前一节介绍的方法通过内核启动参数来向它们传递参数, 如果编译成模块, 则可以通过命令行在插入模块时传递参数, 或者在运行时, 通过 sysfs
来设置或读取模块数据.
Sysfs
是一个基于内存的文件系统, 实际上它基于ramfs
, sysfs
提供了一种把内核数据结构, 它们的属性以及属性与数据结构的联系开放给用户态的方式, 它与 kobject
子系统紧密地结合在一起, 因此内核开发者不需要直接使用它, 而是内核的各个子系统使用它. 用户要想使用 sysfs
读取和设置内核参数, 仅需装载 sysfs
就可以通过文件操作应用来读取和设置内核通过 sysfs
开放给用户的各个参数:
mkdir -p /sysfs
mount -t sysfs sysfs /sysfs
注意, 不要把 sysfs
和 sysctl
混淆, sysctl
是内核的一些控制参数, 其目的是方便用户对内核的行为进行控制, 而 sysfs
仅仅是把内核的 kobject
对象的层次关系与属性开放给用户查看, 因此 sysfs
的绝大部分是只读的, 模块作为一个 kobject
也被出口到 sysfs
, 模块参数则是作为模块属性出口的, 内核实现者为模块的使用提供了更灵活的方式, 允许用户设置模块参数在 sysfs
的可见性并允许用户在编写模块时设置这些参数在 sysfs
下的访问权限, 然后用户就可以通过 sysfs
来查看和设置模块参数, 从而使得用户能在模块运行时控制模块行为.
相关资料链接:
用户空间与内核空间数据交换的方式(6)——模块参数与sysfs:http://www.cnblogs.com/hoys/archive/2011/04/10/2011470.html
2.3 debugfs文件系统
内核开发者经常需要向用户空间应用输出一些调试信息, 在稳定的系统中可能根本不需要这些调试信息, 但是在开发过程中, 为了搞清楚内核的行为, 调试信息非常必要, printk可能是用的最多的, 但它并不是最好的, 调试信息只是在开发中用于调试, 而 printk
将一直输出, 因此开发完毕后需要清除不必要的 printk
语句, 另外如果开发者希望用户空间应用能够改变内核行为时, printk
就无法实现.
因此, 需要一种新的机制, 那只有在需要的时候使用, 它在需要时通过在一个虚拟文件系统中创建一个或多个文件来向用户空间应用提供调试信息.
有几种方式可以实现上述要求:
- 使用
procfs
, 在/proc
创建文件输出调试信息, 但是procfs
对于大于一个内存页(对于x86
是4K
)的输出比较麻烦, 而且速度慢, 有时回出现一些意想不到的问题. - 使用
sysfs
(2.6
内核引入的新的虚拟文件系统), 在很多情况下, 调试信息可以存放在那里, 但是sysfs主要用于系统管理,它希望每一个文件对应内核的一个变量,如果使用它输出复杂的数据结构或调试信息是非常困难的. - 使用
libfs
创建一个新的文件系统, 该方法极其灵活, 开发者可以为新文件系统设置一些规则, 使用libfs
使得创建新文件系统更加简单, 但是仍然超出了一个开发者的想象.
为了使得开发者更加容易使用这样的机制, Greg Kroah-Hartman
开发了 debugfs
(在 2.6.11
中第一次引入), 它是一个虚拟文件系统, 专门用于输出调试信息, 该文件系统非常小, 很容易使用, 可以在配置内核时选择是否构件到内核中, 在不选择它的情况下, 使用它提供的API的内核部分不需要做任何改动.
相关资料链接:
用户空间与内核空间数据交换的方式(1)——debugfs:http://www.cnblogs.com/hoys/archive/2011/04/10/2011124.html
Linux内核里的DebugFS:http://www.cnblogs.com/wwang/archive/2011/01/17/1937609.html
Linux驱动调试的Debugfs的使用简介:http://soft.chinabyte.com/os/110/12377610.shtml
Linux Debugfs文件系统介绍及使用:http://blog.sina.com.cn/s/blog_40d2f1c80100p7u2.html
Linux内核里的DebugFS:http://www.cnblogs.com/wwang/archive/2011/01/17/1937609.html
Debugging the Linux Kernel with debugfs:http://opensourceforu.com/2010/10/debugging-linux-kernel-with-debugfs/
debugfs-seq_file:http://lxr.free-electrons.com/source/drivers/base/power/wakeup.c
Linux Debugfs文件系统介绍及使用:http://blog.sina.com.cn/s/blog_40d2f1c80100p7u2.html
Linux 文件系统:procfs, sysfs, debugfs 用法简介:http://www.tinylab.org/show-the-usage-of-procfs-sysfs-debugfs/
用户空间与内核空间数据交换的方式(1)——debugfs:http://www.cnblogs.com/hoys/archive/2011/04/10/2011124.html
Linux 运用debugfs调试方法:http://www.xuebuyuan.com/1023006.html
2.4 relayfs文件系统
relayfs
是一个快速的转发(relay
)数据的文件系统, 它以其功能而得名. 它为那些需要从内核空间转发大量数据到用户空间的工具和应用提供了快速有效的转发机制.
Channel
是 relayfs
文件系统定义的一个主要概念, 每一个 channel
由一组内核缓存组成, 每一个 CPU
有一个对应于该 channel
的内核缓存, 每一个内核缓存用一个在 relayfs
文件系统中的文件文件表示, 内核使用 relayfs
提供的写函数把需要转发给用户空间的数据快速地写入当前 CPU
上的 channel
内核缓存, 用户空间应用通过标准的文件 I/
O函数在对应的 channel
文件中可以快速地取得这些被转发出的数据 mmap
来. 写入到 channel
中的数据的格式完全取决于内核中创建channel
的模块或子系统.
relayfs
的用户空间API
:
relayfs
实现了四个标准的文件 I/O
函数, open、mmap、poll和close
注意 : 用户态应用在使用上述 API 时必须保证已经挂载了 relayfs 文件系统, 但内核在创建和使用 channel时不需要relayfs 已经挂载. 下面命令将把 relayfs 文件系统挂载到 /mnt/relay.
相关资料链接:
用户空间与内核空间数据交换的方式(4)——relayfs:http://www.cnblogs.com/hoys/archive/2011/04/10/2011270.html
Relay:一种内核到用户空间的高效数据传输技术:https://www.ibm.com/developerworks/cn/linux/l-cn-relay/
2.5 seq_file
一般地, 内核通过在 procfs
文件系统下建立文件来向用户空间提供输出信息, 用户空间可以通过任何文本阅读应用查看该文件信息, 但是 procfs
有一个缺陷, 如果输出内容大于1个内存页, 需要多次读,因此处理起来很难, 另外, 如果输出太大, 速度比较慢, 有时会出现一些意想不到的情况, Alexander Viro
实现了一套新的功能, 使得内核输出大文件信息更容易, 该功能出现在 2.4.15
(包括 2.4.15
)以后的所有 2.4
内核以及 2.6
内核中, 尤其是在 2.6
内核中,已经大量地使用了该功能
相关资料链接:
用户空间与内核空间数据交换的方式(3)——seq_file:http://www.cnblogs.com/hoys/archive/2011/04/10/2011261.html
内核proc文件系统与seq接口(4)—seq_file接口编程浅析:http://blog.chinaunix.net/uid-20543672-id-3235254.html
Linux内核中的seq操作:http://www.cnblogs.com/qq78292959/archive/2012/06/13/2547335.html
seq_file源码分析:http://www.cppblog.com/csjiaxin/articles/136681.html
用序列文件(seq_file)接口导出常用数据结构:http://blog.chinaunix.net/uid-317451-id-92670.html
seq_file机制:http://blog.csdn.net/a8039974/article/details/24052619
3 printk
在内核调试技术之中, 最简单的就是 printk
的使用了, 它的用法和C语言应用程序中的 printf
使用类似, 在应用程序中依靠的是 stdio.h
中的库, 而在 linux
内核中没有这个库, 所以在 linux
内核中,实现了自己的一套库函数, printk
就是标准的输出函数
相关资料链接:
linux内核调试技术之printk:http://www.cnblogs.com/veryStrong/p/6218383.html
调整内核printk的打印级别:http://blog.csdn.net/tonywgx/article/details/17504001
linux设备驱动学习笔记–内核调试方法之printk:http://blog.csdn.net/itsenlin/article/details/43205983
4 ftrace && trace-cmd
4.1 trace && ftrace
Linux
当前版本中, 功能最强大的调试、跟踪手段. 其最基本的功能是提供了动态和静态探测点, 用于探测内核中指定位置上的相关信息.
静态探测点, 是在内核代码中调用 ftrace
提供的相应接口实现, 称之为静态是因为, 是在内核代码中写死的, 静态编译到内核代码中的, 在内核编译后, 就不能再动态修改. 在开启 ftrace
相关的内核配置选项后, 内核中已经在一些关键的地方设置了静态探测点, 需要使用时, 即可查看到相应的信息.
动态探测点, 基本原理为 : 利用 mcount
机制, 在内核编译时, 在每个函数入口保留数个字节, 然后在使用 ftrace
时, 将保留的字节替换为需要的指令, 比如跳转到需要的执行探测操作的代码。
ftrace
的作用是帮助开发人员了解 Linux
内核的运行时行为, 以便进行故障调试或性能分析.
最早 ftrace
是一个 function tracer
, 仅能够记录内核的函数调用流程. 如今 ftrace
已经成为一个
framework
, 采用 plugin
的方式支持开发人员添加更多种类的 trace
功能.
Ftrace
由 RedHat
的 Steve Rostedt
负责维护. 到 2.6.30
为止, 已经支持的 tracer
包括 :
这里还没有列出所有的 tracer
, ftrace
是目前非常活跃的开发领域, 新的 tracer
将不断被加入内核。
相关资料链接:
ftrace和它的前端工具trace-cmd(深入了解Linux系统的利器):http://blog.yufeng.info/archives/1012
ftrace 简介:https://www.ibm.com/developerworks/cn/linux/l-cn-ftrace/
内核性能调试–ftrace:http://blog.chinaunix.net/uid-20589411-id-3501525.html
使用 ftrace 调试 Linux 内核,第 1 部分:https://www.ibm.com/developerworks/cn/linux/l-cn-ftrace1
ftrace的使用:http://blog.csdn.net/cybertan/article/details/8258394
[转]Linux内核跟踪之trace框架分析:http://blog.chinaunix.net/uid-24063584-id-2642103.html
Linux trace使用入门:http://blog.csdn.net/jscese/article/details/46415531
4.2 ftrace前端工具trace-cmd
- trace-cmd 介绍
trace-cmd
和 开源的 kernelshark
均是内核Ftrace
的前段工具, 用于分分析核性能.
他们相当于是一个 /sys/kernel/debug/tracing
中文件系统接口的封装, 为用户提供了更加直接和方便的操作.
- 使用
# 收集信息
sudo trace-cmd reord subsystem:tracing
# 解析结果
#sudo trace-cmd report
trace-cmd: A front-end for Ftrace:https://lwn.net/Articles/410200/
其本质就是对/sys/kernel/debug/tracing/events
下各个模块进行操作, 收集数据并解析
-
内核
+关注
关注
3文章
1372浏览量
40282 -
数据
+关注
关注
8文章
7006浏览量
88947 -
Linux
+关注
关注
87文章
11296浏览量
209348 -
开发
+关注
关注
0文章
370浏览量
40836
发布评论请先 登录
相关推荐
评论