SystemTap是一个Linux调试和性能分析工具,可用于应用层和内核层的分析,但主要侧重内核层。SystemTab可以在不修改内核代码、不重复编译内核、不重启机器的情况下,收集运行内核的信息并使信息可视化。调试人员可以利用它绘制函数调用关系图,打印寄存器信息和调用栈,输出内核中指定变量(可以是局部变量)。它如同一个更加方便prink,方便调试人员观察内核行为,诊断错误异常,分析系统性能。在YAVIS开发过程中,我们使用SystemTap分析包发送和接收情况,并分析通信性能瓶颈。

SystemTap工作流程

SystemTap使用了Kprobe技术探测内核信息,辅以Relayfs向用户传递消息。

SystemTap首先将SystemTap脚本文件翻译成C源文件。这个C源文件实际上是一个内核模块,实现了脚本文件中描述的功能。接着SystemTap编译源文件获得二进制模块文件,并动态加载模块。模块被载入运行内核后,会报告脚本文件中指定的一些事件。事件会触发脚本文件中编写的处理函数,执行相关操作。一般操作内容是:收集所需信息,并通过标准输出打印给用户。SystemTap会话结束于用户发出中断信号,即Ctrl + C,内核模块将随之被安全卸载。

SystemTap提供了一些内置函数,帮助我们快速开发测试脚本。常用的内置函数如:

print(str) - 打印str的值

printf(fmt) - 如同C语言的printf函数

probefunc() - 返回当前探测函数的函数名

execname() - 返回当前进程的名字

pid() - 返回当前进程ID

uid() - 返回当前进程用户ID

cpu() - 返回运行当前进程的CPU号

另外一些内置功能以Tapset的形式出现。Tapset相当于SystemTap的库。它提供的功能不仅仅是函数,还包括一些预定义的探测点,如:

timer.ms(N) - 每N毫秒探测一次(用于性能测试)

begin - 探测模块加载时执行一次

当然,用户也可以开发自己的Tapset。

SystemTap的使用

在CentOS中SystemTap可以用下面命令安装升级:

sudo yum installsystemtapsystemtap-runtime

编写脚本后,使用这个命令执行:

stap

注意:如果探测的是模块,要确保模块被复制到/lib/modules//中,否则脚本解析时会在module处出错。

SystemTap脚本语言

SystemTap语言是一种与C语言和awk语言类似的脚本语言。限于篇幅,这里并不系统地介绍SystemTap语言,而是结合毕业设计的调试场景,使用例子说明SystemTap的语法特征和编程结构。

#!/usr/bin/stap

probe module("yavis").function("*").call {

printf("%s -> %s\n", thread_indent(1), probefunc())

}

probe module("yavis").function("*").return {

printf("%s -> %s\n", thread_indent(-1), probefunc());

}

上述代码的功能是输出YAVIS的代码调用关系图。第一行描述脚本采用的解释器是stap程序。第二行表示在yavis模块中所有函数中插入探针,并在这些函数调用时触发第三行的代码。第三行代码向标准输出打印一串信息,信息包括当前函数的名字,由内置的probefunc收集。第五至第七行代码与上面的类似,只是在函数返回时触发。这样,所有YAVIS模块的函数在调用时输出函数名,返回时再次输出函数名,同时由内置的thread_indent函数负责自动的缩进,最终绘制了整个YAVIS模块的函数调用关系图。

#!/usr/bin/stap

probe module("yavis").function("yavis_poll") {

if ($revt->type == 0) {

printf("-- package received --\n")

printf("revt.msg_len = %d\n", $revt->msg_len)

for (i = 0; i < $revt->msg_len; i++) {

printf("%x", $revt->rbuff[i])

}

printf("\n")

} else if ($sevt->type == 0) {

printf("-- package sent --\n");

}

}

probe module("yavis").function("yavis_tx") {

printf("-- sending package --\n");

printf("skb->len = %d\n", $skb->len)

for (j = 0; j < $skb->len; j++) {

printf("%x", $skb->data[j])

}

printf("\n")

}

上面这段脚本可以让我们在发送和接收过程中查看数据。注意结构体类型的数据,无论指针与否,一律使用->方式访问成员变量。

附注

systemtap可由包管理器直接安装。但是想探测较新版本的内核,建议手动编译git仓库中的最新版本systemtap。当然由于systemtap开发相对内核开发有些许置后,所以最新的systemtap一般没法探测最新版本的内核。具体能不能,留意stap --version命令的输出。

参考

[1] SystemTap: Instrumenting the Linux Kernel for Analyzing Performance and Functional Problems. IBM, 2009.

systemtap调试linux内核源码,内核调试工具SystemTap:适合懒人的printk替代品相关推荐

  1. 手机电脑自适应导航源码php,自适应各终端懒人网址导航源码 v2.0

    自适应各终端懒人网址导航源码. V2.0版本是在原1.8版本的基础上修复和增加了些功能.推荐直接使用新版本,舍弃旧版本,后期会继续不定期更新. 测试环境: 宝塔Nginx -Tengine2.2.3的 ...

  2. java clone 源码_Java Clone方法之懒人实现

    在Java的Object类中定义了(protected)clone()方法,如果自己的类需要clone方法的话需要实现Cloneable接口,并重写clone()方法和将方法访问级别改为(public ...

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

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

  4. SUSE Linux Enterprise Server 安装内核源码及部署crash调试环境,分析内核崩溃文件(基于sles 15.2)

    实验环境: yg-net-static:~ # uname -a Linux yg-net-static 5.3.18-22-default #1 SMP Wed Jun 3 12:16:43 UTC ...

  5. Linux内核源码分析--内核启动之(3)Image内核启动(C语言部分)(Linux-3.0 ARMv7) 【转】...

    原文地址:Linux内核源码分析--内核启动之(3)Image内核启动(C语言部分)(Linux-3.0 ARMv7) 作者:tekkamanninja 转自:http://blog.chinauni ...

  6. Linux内核移植之一:内核源码结构与Makefile分析

    内容来自 韦东山<嵌入式Linux应用开发完全手册> 一.内核介绍 1.版本及其特点 Linux内核的版本号可以从源代码的顶层目录下的Makefile中看到,比如下面几行它们构成了Linu ...

  7. android 修改编译内核源码 对抗反调试

    0×00  写在前面 攻防对立.程序调试与反调试之间的对抗是一个永恒的主题.在安卓逆向工程实践中,通过修改和编译安卓内核源码来对抗反调试是一种常见的方法.但网上关于此类的资料比较少,且都是基于AOSP ...

  8. 深入分析Linux内核源码oss.org.cn/kernel-book/

    本html页面地址:http://oss.org.cn/kernel-book/ 深入分析Linux内核源码 前言         第一章 走进linux 1.1 GNU与Linux的成长 1.2 L ...

  9. ubuntu下wget下载Linux内核源码、make生成.config文件

    根据资料,如果要调试Linux内核源码,需要自己编译内核源码:原因是,一般下载的内核并不是为调试而编译的,要在编译时开启 "Compile the kernel with debug inf ...

最新文章

  1. iOS开发-UISwipeGestureRecognizer滑动手势
  2. 配置DATAGUARD 时关于 LOG_FILE_NAME_CONVERT配置错误的解决
  3. 如何使用Java 8流快速替换列表中的元素
  4. JVM虚拟机-Class文件之魔数
  5. Android 原生 MediaPlayer 和 MediaCodec 的区别和联系(二)
  6. 别动我的代码!聊聊那些代码保护的艺术
  7. Google全球服务器根域名的IP地址
  8. c语言中一些公用的方法
  9. jQuery支持移动触摸设备的Lightbox插件
  10. 不知道前端课程学什么?这份完整的web前端课程大纲分享给你
  11. c语言中compar的用法,compare的用法知识整理
  12. easyUI动态加载combobox
  13. [Bullet3]常见物体和初始化
  14. 5分钟搭建私人Java博客系统——Tale
  15. java合并果子_合并果子(经典优先队列)
  16. PS教程:如何拼图调色出高大上的作品
  17. 强化学习--蒙特卡洛法
  18. 上传并下载excel表格
  19. vr虚拟现实技术的前景!对未来发展带来有利的趋势吗?
  20. 爬虫实战4:爬取猫眼电影排名Top100的详细数据保存到csv文件

热门文章

  1. 二叉树的创建及各种遍历
  2. mui toast自定义样式
  3. 【面试刷题复习】更新中 2021.8.30
  4. doris历程_Doris简史-为分析而生的11年
  5. [08001] Could not create connection to database server. Attempted reconnect 3 times. Giving up.解决办法
  6. 基于Python3-Pygame的植物大战僵尸小游戏
  7. No module named ‘win32gui‘ 的解决方法(踩坑之旅)
  8. WSL2安装GUI界面与音视频
  9. android预览界面显示不全,Android SurfaceView Camera 预览显示不全(画面拉伸)
  10. 盛科交换机配置命令_cisco2960交换机 清除配置的命令