一、 Systemtap简介

systemtap最早用于kernel分析,扩展了utrace/uprobe模块后可以用于监视用户程序。Systemtap允许使用者向内核代码或者用户空间的程序设置一个观测点,当内核代码或者用户程序运行到这个观测点时,使用者有机会执行一个自己编写的内核函数,读取该观测点上下文,进行分析与统计。常见的用法有函数调用的Callgraph生成,程序性能分析时用到的FlameGraph,内存瓶颈分析,网络流量统计等。例如下面的python脚本性能分析时画出的FlameGraph:

二、 systemtap安装

在debian8上的编译安装,首先下载systemtap-3.1,
确认gcc、make等基础编译环境已经安装好,然后:

$sudo apt-get install gettext
$sudo apt-get install elfutils
$sudo apt-get install libdw-dev
$cd systemtap-3.1
$./configure
$make & sudo make install

编译完成后,在systemtap-3.1目录下会生成stap-prep,执行./stap-prep按照提示安装缺少的linux headers和debug包

三、 systemtap基本使用

Systemtap与ptrace相比,在易用性上有明显优势,ptrace要求写一段复杂的C代码进调用ptrace API完成追踪的功能,而systemtap只需要提供一个高级的awk-like脚本,格式为:

probe event {statements}

其中probe是脚本关键字,表示定义一个探测点,event是需要探测的事件名字,例如syscall.open, process(‘procName’).function(‘funcName’),一个简单的探测脚本只需要几行:

probe system.open
{printf("%s open %s\n", pid(), user_string($filename))
}

具体用法可以参见:https://sourceware.org/systemtap/SystemTap_Beginners_Guide.pdf

四、 systemtap原理

为了实现探测,systemtap主要对脚本进行以下几步处理:

  1. stap命令解析systemtap脚本,在/usr/share/systemtap/tapset/找到输入脚本依赖的所有库脚本
  2. 把systemtap脚本翻译成C代码,然后调用GCC把C代码编译成一个内核模块,翻译的过程中需要用到被探测的程序的符号信息,所以目标程序是需要包含debug信息的或者是通过-d参数向systemtap提供符号表信息
  3. Staprun命令通过调用modprobe命令加载编译后的模块到内核,同时打开probes开关
  4. 事件触发时就执行我们写的handler,所有事件完成最后卸载内核模块

###内核模块###
内核模块是为了精简linux kernel而设计的,对于一些不一定需要的模块,启动时并不需要加载,等真正需要用的时候再通过内核提供的接口动态加载,可以保证内核比较精简的情况下,又不失可扩展的灵活性。内核模块可以被单独编译,但不能单独运行,必须通过内核加载后才能发挥作用,内核模块并没有main函数,主要有两种写法:

#include <linux/module.h>       /* Needed by all modules */
#include <linux/kernel.h>       /* Needed for KERN_INFO */int init_module(void)
{printk(KERN_INFO "Hello world 1.\n");/*  * A non 0 return means init_module failed; module can't be loaded. */return 0;
}void cleanup_module(void)
{printk(KERN_INFO "Goodbye world 1.\n");
}

上面的写法需要实现两个接口,init_module和cleanup_module,名字不能修改,但在linux2.4以后,支持自己定义内核模块入口等名字,只需要用module_init和module_exit宏来指定:

#include <linux/module.h>       /* Needed by all modules */
#include <linux/kernel.h>       /* Needed for KERN_INFO */
#include <linux/init.h>         /* Needed for the macros */static int __init hello_2_init(void)
{printk(KERN_INFO "Hello, world 2\n");return 0;
}static void __exit hello_2_exit(void)
{printk(KERN_INFO "Goodbye, world 2\n");
}module_init(hello_2_init);
module_exit(hello_2_exit);

systemtap使用的是第一种写法,可以指定参数查看systemtap生成的C代码来确定:
stap -v test.stp -p 3
可以看到生成的C代码中有#include “runtime.h”,其中又包含了

#include <linux/runtime.h>

然后linux/runtime.h中实现了init_module和cleanup_module接口

systemtap使用kprobe模块来监测内核,用uprobe模块监测用户空间程序,两个模块工作原理类似,平时也主要需要调试用户程序,所以只简单写一下uprobes模块的原理,具体使用查看man手册。

uprobe的入口API是:

int uprobe_register(struct inode *inode, loff_t offset, struct uprobe_consumer *uc)
@inode: the file in which the probe has to be placed.
@offset: offset from the start of the file.
@uc: information on howto handle the probe..

注册一个探测点,其中inode是目标程序的文件inode,offset是探测点距离elf文件加载开始位置的偏移量,uc是自定义的事件处理器,可以发现uprobe是基于文件和符号地址工作的,所以所有从这个elf文件启动的进程都将受uprobe模块监测,并且如果目标进程是多线程的,每个线程都会触发探测点事件。
不难看出,上面这个接口的关键在于找到这个偏移量,那么怎么找这个便宜量呢,举个例子假设我们有一个已经在运行的进程a.out,我们想监测a.out中名字为reg_server的函数,首先我们查看a.out进程的内存空间分布:

zt@debian:~$cat /proc/`pgrep a.out`/maps|grep a.out
08048000-080ac000 r-xp 00000000 08:01 791802     /home/zt/server/bin/a.out
080ac000-080ae000 rw-p 00063000 08:01 791802     /home/zt/server/bin/a.out

第二列是段的权限,可以看出上面的段是只读的,下面的是读写的,所以上面的是.text,下面的是.data,那现在要找的reg_server函数是在.text中,加载的开始地址是0x08048000我们再去看看a.out中这个函数的地址:

zt@debian:~/server$ readelf -Ws ./bin/a.out | c++filt | grep 'reg_server'153: 08090183    13 OBJECT  LOCAL  DEFAULT   15 unreg_server155: 08090d14    11 OBJECT  LOCAL  DEFAULT   15 reg_server848: 08060e80   980 FUNC    GLOBAL DEFAULT   13 unreg_server1581: 08061260  1503 FUNC    GLOBAL DEFAULT   13 reg_server

可以看到函数reg_server的地址为0x08061260,最终计算偏移量为0x08061260-0x08048000=0x19260,找到这个地址,uprobe模块会把该地址的指令替换为0xcc(即int 3指令),当程序执行到这里的时候就会产生一个sigtrap信号,用户程序就停到这里,然后执行uprobe_consumer 参数指定的自定义的函数,完成一次事件触发及事件处理

Systemtap原理简介相关推荐

  1. javascript原理_JavaScript程序包管理器工作原理简介

    javascript原理 by Shubheksha 通过Shubheksha JavaScript程序包管理器工作原理简介 (An introduction to how JavaScript pa ...

  2. Nginx 反向代理工作原理简介与配置详解

    Nginx 反向代理工作原理简介与配置详解 测试环境 CentOS 6.8-x86_64 nginx-1.10.0 下载地址:http://nginx.org/en/download.html 安装 ...

  3. DeepLearning tutorial(1)Softmax回归原理简介+代码详解

    FROM: http://blog.csdn.net/u012162613/article/details/43157801 DeepLearning tutorial(1)Softmax回归原理简介 ...

  4. DeepLearning tutorial(3)MLP多层感知机原理简介+代码详解

    FROM:http://blog.csdn.net/u012162613/article/details/43221829 @author:wepon @blog:http://blog.csdn.n ...

  5. DeepLearning tutorial(4)CNN卷积神经网络原理简介+代码详解

    FROM: http://blog.csdn.net/u012162613/article/details/43225445 DeepLearning tutorial(4)CNN卷积神经网络原理简介 ...

  6. 【Android 异步操作】Handler ( 主线程中的 Handler 与 Looper | Handler 原理简介 )

    文章目录 一.主线程中的 Handler 与 Looper 二.Handler 原理简介 一.主线程中的 Handler 与 Looper Android 系统中 , 点击图标启动一个应用进程 , 就 ...

  7. 量子计算机编程原理简介 和 机器学习

    量子计算机编程原理简介 和 机器学习 本文翻译自D-Wave公司网站 www.dwavesys.com/en/dev-tutorial-intro.html D-wave公司在2007年就声称实现了1 ...

  8. DL之CNN:卷积神经网络算法简介之原理简介——CNN网络的3D可视化(LeNet-5为例可视化)

    DL之CNN:卷积神经网络算法简介之原理简介--CNN网络的3D可视化(LeNet-5为例可视化) CNN网络的3D可视化 3D可视化地址:http://scs.ryerson.ca/~aharley ...

  9. DL之CNN:卷积神经网络算法简介之原理简介(步幅/填充/特征图)、七大层级结构(动态图详解卷积/池化+方块法理解卷积运算)、CNN各层作用及其可视化等之详细攻略

    DL之CNN:卷积神经网络算法简介之原理简介(步幅/填充/特征图).七大层级结构(动态图详解卷积/池化+方块法理解卷积运算).CNN各层作用及其可视化等之详细攻略 目录 CNN 的层级结构及相关概念 ...

最新文章

  1. 高 NPS 背后的专业服务体系是如何炼成的?
  2. codemirror mysql_CodeMirror 实现 JavaScript、 MySql 关键字的变色和自动实时提示 autocomplete...
  3. [导入]70后、80后、90后的区别
  4. vue项目示例代码git_您应该了解的5个Git命令以及代码示例
  5. 7. Oracle数据加载和卸载
  6. Linux文件系统管理命令(第二版)
  7. javascript测试框架 Mocha 实例教程
  8. SSH报错:packet_write_wait: Connection to xxx Broken pipe 解决
  9. 图像语义分割(14)-FastFCN: 重新思考语义分割模型主干网络中的扩张卷积
  10. CADD课程学习(2)-- 靶点晶体结构信息
  11. java时间为什么只显示到日_java-为什么此日期未在格林尼治标准时间显示?
  12. 大多数计算机有几个cpu,多处理器分配
  13. 前端监控:回放录制库 rrweb
  14. CDR插件开发之Addon插件007 - Addon插件简介和案例演示
  15. 期货开户手续费组成和最低价
  16. 根文件系统(rootfs)理解
  17. winhex入门基础知识
  18. linux设置时间服务器
  19. 晶体管发明往事:误打误撞,反目成仇,共享诺贝尔奖
  20. Windows环境下视频文件转成RTSP视频流和RTMP流

热门文章

  1. error Link2001
  2. 【BZOJ5060】魔方国 特判
  3. android直播视频编码,Android手机直播之视频编码技术
  4. java设计模式转发_Java设计模式之《单例模式》及应用场景(转发:http://www.cnblogs.com/V1haoge/p/6510196.html)...
  5. 03-05 创建和编辑AutoCAD实体(五) 使用图层、颜色和线型(3)使用线型
  6. 安装pycharm专业版
  7. uniapp 下拉刷新、上拉加载更多、最常见的节流场景
  8. camunda-external-task-java外部任务项目启动失败,Error creating bean with name ‘externalTaskClient‘: .....
  9. camera2 拍照超时_Android Camera2 拍照(三)——切换摄像头,延时拍摄和闪光模式-阿里云开发者社区...
  10. 输入字符串,找出其中大写字母、小写字母、空格、数字、以及其他字符各有多少。