名称 | 说明 |
---|---|
begin | systemtap 会话打开 |
end | systemtap会话结束 |
kernel.function(“sys_open”) | kernel 的sys_open函数 |
syscall.close.return | close被系统调用 |
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语言头文件引入 用 %{ 和 %} 包裹, 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, ¤t->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