当前位置: 首页 > 工具软件 > SystemTap > 使用案例 >

SystemTap基本用法介绍

夏宪
2023-12-01

可探查的事件

名称说明
beginsystemtap 会话打开
endsystemtap会话结束
kernel.function(“sys_open”)kernel 的sys_open函数
syscall.close.returnclose被系统调用
module(“ext3”).statement(0xdeadbeef)ext3文件系统驱动中的地址
timer.ms(200)每200毫秒触发一次的计时器
timer.profile每个cpu时钟周期触发的计时器
perf.hw.cache_misses缓存未名中的数量
procfs(“status”).read一个进程尝试读取(synthetic合成)文件
process(“a.out”).statement(“*@main.c:200”)a.out的200行
probe kernel.function(“*@net/socket.c”) { }内核源文件net/socket.c所有函数入口加探针
probe kernel.function(“*@net/socket.c”).return { }内核源文件net/socket.c所有函数返回加探针

可打印的内容

函数或变量说明
tid()当前线程id
pid()当前线程所属的进程id
uid()当前的用户id
execname()当前进程名称
cpu()cpu编号
gettimeofday_s()从启动到当前的时间
get_cycles()硬件周期快照
pp()当前正在处理的探针描述符
ppfunc()探针位置的函数名
$$vars列出当前域的变量名
print_backtrace()打印内核回溯信息
print_ubacktrace()打印用户空间回溯信息

打印搜索路径

stap -p1 -vv -e ’probe begin { }’ > /dev/null

#会打印出搜索stp脚本的路径

添加自定义路径

通过参数 -I DIR

# cat /opt/app/systemtap/scripts/myscripts/common-time.stp
global __time_vars
function timer_begin (name) { __time_vars[name] = __time_value () }
function timer_end (name) { return __time_value() - __time_vars[name] }
# cat /opt/app/systemtap/scripts/myscripts/time-default.stp
unction __time_value () { return gettimeofday_us () }
# cat /opt/app/systemtap/scripts/time-test.stp
probe begin
{
      timer_begin ("bench")
        for (i=0; i<100; i++) ;
          printf ("%d cycles\n", timer_end ("bench"))
            exit ()
}

# 运行脚本, 这里我们使用了自定义搜索目录/opt/app/systemtap/scripts/myscripts 下的stp脚本
sudo stap -I /opt/app/systemtap/scripts/myscripts time-test.stp
1 cycles

嵌入c语言

c语言头文件引入 用 %{%} 包裹, function内容体也用 %{ 和 **%}**包裹。

c语言通过宏STAP_ARG_* 来使用函数入参

c语言通过宏STAP_RETVALUE 来返回数据

执行脚本需要添加选项 -g

下面来看一个返回进程名的例子:

# cat embedded-C.stp
%{
#include <linux/sched.h>
#include <linux/list.h>
%}
function task_execname_by_pid:string (pid:long) %{
  struct task_struct *p;
  struct list_head *_p, *_n;
  list_for_each_safe(_p, _n, &current->tasks) {
    p = list_entry(_p, struct task_struct, tasks);
    if (p->pid == (int)STAP_ARG_pid)
      snprintf(STAP_RETVALUE, MAXSTRINGLEN, "%s", p->comm);
  }
%}
probe begin
{
  printf("%s(%d)\n", task_execname_by_pid(target()), target())
  exit()
}
pgrep vim
# 获取vim进程id  1985359

#执行脚本
sudo stap -g embeded-c.stp -x 1985359
#输出
vim(1985359)


#如果报错
ERROR: Couldn't insert module '/tmp/stapexA1WS/*.ko': Invalid module format

#添加如下选项执行脚本解决
sudo stap -B CONFIG_MODVERSIONS=y -g embeded-c.stp -x 1985359
 类似资料: