GoGPT Best VPN GoSearch

OnWorks 网站图标

stap - 云端在线

通过 Ubuntu Online、Fedora Online、Windows 在线模拟器或 MAC OS 在线模拟器在 OnWorks 免费托管服务提供商中运行 stap

这是可以使用我们的多个免费在线工作站之一在 OnWorks 免费托管服务提供商中运行的命令 stap,例如 Ubuntu Online、Fedora Online、Windows 在线模拟器或 MAC OS 在线模拟器

程序:

您的姓名


stap - systemtap 脚本翻译器/驱动程序

概要


装订 [ 配置 ] 文件名 [ 争论 ]
装订 [ 配置 ] - [ 争论 ]
装订 [ 配置 ] -e SCRIPT [ 争论 ]
装订 [ 配置 ] -l 探测 [ 争论 ]
装订 [ 配置 ] -L 探测 [ 争论 ]
装订 [ 配置 ] --转储探针类型
装订 [ 配置 ] --dump-probe-别名
装订 [ 配置 ] --转储功能

商品描述


这个 装订 程序是 Systemtap 工具的前端。 它接受探测指令
用简单的特定领域语言编写,将这些指令翻译成 C 代码,
编译此 C 代码,并将生成的模块加载到正在运行的 Linux 内核或
DynInst 用户空间修改器,用于执行请求的系统跟踪/探测功能。 你
可以从标准输入(使用 - 而不是
FILENAME),或从命令行(使用 -e SCRIPT)。 程序运行直到它
被用户打断,或者脚本自愿调用 出口() 功能,或通过
足够数量的软错误。

所描述的语言 SCRIPT 语言 下面的部分是严格键入的,
富有表现力的、无声明的、程序化的、原型友好的,并受到启发 AWKC.
它允许系统中的源代码点或事件与处理程序相关联,
是同步执行的子程序。 它在概念上有点类似于
中的“断点命令列表” GDB 调试器。

配置


systemtap 转换器支持以下选项。 任何其他选项都会打印一个列表
支持的选项。 像往常一样,可以在命令行上给出选项。 如果文件
$SYSTEMTAP_DIR/rc 存在,选项也从那里加载并首先解释。
(如果未设置,$SYSTEMTAP_DIR 默认为 $HOME/.systemtap。)

- 使用标准输入而不是给定的 FILENAME 作为探测语言输入,除非 -e
给出了脚本。

-h - 帮帮我
显示帮助信息。

-V - 版
显示版本信息。

-p 通过 NUM 后停止。 通行证编号为 1-5:解析、详细说明、翻译、
编译,运行。 见 处理 详细信息。

-v 增加所有通行证的详细程度。 产生更多的信息量 (?)
每次选项重复输出。

--副总裁 ABCDE
在每次传递的基础上增加详细程度。 例如,“--vp 002”添加 2 个单位的
仅通过 3 的冗长。 组合“-v --vp 00004”增加了1个冗长单位
对于所有通行证,对于通行证 4,还有 5 个。

-k 在所有处理后保留临时目录。 这可能有助于
检查生成的 C 代码,或重用已编译的内核对象。

-g 大师模式。 启用对不安全的专家级结构(如嵌入式 C)的解析。

-P 序言搜索模式。 这相当于 --prologue-searching=always。
激活试探法以解决函数的错误调试信息
参数 $context 变量。

-u 未优化模式。 在此期间禁用未使用的代码省略和许多其他优化
阐述/翻译。

-w 抑制警告模式。 禁用所有警告消息。

-W 将所有警告视为错误。

-b 使用批量模式(percpu 文件)进行内核到用户的数据传输。 使用 合并
程序稍后将它们多路复用。

-t 收集有关探针执行次数和平均数量的计时信息
在每个探测点上花费的时间。 还显示了每个探测点的推导。

-s 使用 NUM 兆字节缓冲区进行内核到用户的数据传输。 在多处理器上
批量模式,这是每个处理器的数量。

-I DIR 将给定的目录添加到 tapset 搜索目录中。 见说明
详情通过2。

-D NAME = VALUE
将给定的 C 预处理器指令添加到模块 Makefile。 这些可以用
覆盖下面描述的限制参数。

-B NAME = VALUE
将给定的 make 指令添加到内核模块构建的 make 调用中。 这些
可用于添加或覆盖 kconfig 选项。

-a
对给定的目标架构使用交叉编译模式。 这需要
访问交叉编译器和内核构建树,并与 -B
CROSS_COMPILE=arch-工具-前缀--r /构建/树 选项​​。

--修改信息 NAME = VALUE
将名称/值对作为 MODULE_INFO 宏调用添加到生成的模块。 这个
可能有助于通知或覆盖内核中的各种与模块相关的检查。

-G NAME = VALUE
调用 staprun 时,将全局变量 NAME 的值设置为 VALUE。 这个
适用于在脚本/tapset 中声明为全局的标量变量。

-R DIR 在给定目录中查找 systemtap 运行时源。

-r /目录
在给定的构建树中为内核构建。 也可以设置 SYSTEMTAP_RELEASE
环境变量。

-r RELEASE
在构建树中为内核构建 /lib/modules/RELEASE/构建. 也可以设置
这些因素包括原料奶的可用性以及达到必要粉末质量水平所需的工艺。 SYSTEMTAP_RELEASE 环境变量。

-m 模块
为生成的内核对象模块使用给定的名称,而不是唯一的
随机名称。 生成的内核对象模块被复制到当前
目录。

-d 模块
将给定模块的符号/展开信息添加到内核对象模块中。
这可能会启用来自这些模块/程序的符号追溯,即使它们确实如此
没有在其中放置明确的探针。

--ldd 为 ldd 怀疑为的所有共享库添加符号/展开信息
探测或使用 -d 选项列出的用户空间二进制文件是必需的。
注意:这会使探头模块变得相当大。

--所有模块
相当于为每个内核模块指定“-dkernel”和“-d”
当前加载。 注意:这会使探头模块变得相当大。

-o 文件
将标准输出发送到命名文件。 在批量模式下,percpu 文件将以
FILE_(带 -F 的 FILE_cpu)后跟 cpu 编号。 这支持 时间(3)
FILE 的格式。

-c CMD 启动探测器,运行 CMD,并在 CMD 完成时退出。 这也有效果
将 target() 设置为运行的命令的 pid。

-x 电位诱导衰减 将 target() 设置为 PID。 这允许编写脚本来过滤特定的
过程。 脚本独立于 PID 的生命周期运行。

-e SCRIPT
运行在命令行上指定的给定 SCRIPT。

-E SCRIPT
运行指定的给定 SCRIPT。 除了主脚本之外还运行此脚本
指定,通过 -e,或作为脚本文件。 这个选项可以重复运行
多个脚本,并且可以在列表模式下使用 (-l/-L)。

-l 探测
无需运行探针脚本,只需列出匹配的所有可用探针点
给定的单个探测点。 模式可能包括通配符和别名,但
不是逗号分隔的多个探测点。 处理结果代码将指示
如果没有匹配项,则失败。

-L 探测
类似于“-l”,但列出探测点和脚本级局部变量。

-F 没有 -o 选项,加载模块并启动探测器,然后从模块中分离
让探针继续运行。 使用 -o 选项,在后台运行 staprun 作为守护进程
并显示其pid。

-S 大小[,N]
设置输出文件的最大大小和输出文件的最大数量。 如果
输出文件的大小将超过 尺寸 , systemtap 将输出文件切换到
下一个文件。 如果输出文件的数量超过 N , systemtap 删除
最旧的输出文件。 您可以省略第二个参数。

--跳过-badvars
忽略无法解析或运行时无法访问的上下文变量并替换为
0,没有错误。

--序言搜索[=WHEN]
序言搜索模式。 激活启发式以解决不正确的调试
函数参数 $context 变量的信息。 WHEN 可以是
“从不”、“总是”或“自动”(即通过启发式启用)。 如果缺少 WHEN,则
假设“总是”。 如果缺少该选项,则假定为“自动”。

--suppress-handler-错误
将所有探针处理程序包装成这样的东西

尝试 { ... } 抓住 { 下一个 }

块,这会导致任何运行时错误被悄悄抑制。 抑制错误
不计较 最大错误数 限制。 在这种模式下, 最大跳过 限制是
也被抑制,因此在一个过程中可能会积累许多错误和跳过的探测
脚本的运行时。 任何总体计数仍将在关闭时报告。

- 兼容的 VERSION
禁止最近的脚本语言或与给定不兼容的 Tapset 更改
旧版本的 systemtap。 如果一个更旧的 systemtap 脚本,这可能很有用
无法运行。 有关更多详细信息,请参阅弃用部分。

--检查版本
此选项用于检查活动脚本是否具有任何可能
systemtap 版本特定。 有关更多详细信息,请参阅弃用部分。

--清理缓存
此选项从缓存目录中删除陈旧的条目。 这通常是这样做的
成功运行后自动,但此选项将触发清理
手动然后退出。 有关缓存的更多详细信息,请参阅缓存部分
限制。

- 颜色[=WHEN], - 颜色[=WHEN]
此选项控制错误消息的颜色。 WHEN 可以是“从不”,
“始终”或“自动”(即仅在终端时启用)。 如果缺少 WHEN,则
假设“总是”。 如果缺少该选项,则假定为“自动”。

可以使用 SYSTEMTAP_COLORS 环境变量修改颜色。 格式
必须是形式 key1=val1:key2=val2:key3=val3 ...等等。 有效的键是“错误”,
“警告”、“来源”、“插入符号”和“标记”。 价值观构成选择图形
再现 (SGR) 参数。 请参阅终端的文档以了解
它支持的 SGR。 例如,默认颜色将表示为
error=01;31:warning=00;33:source=00;34:caret=01:token=01. 如果 SYSTEMTAP_COLORS 是
不存在时,将使用默认颜色。 如果为空或无效,则着色为
关闭。

--禁用缓存
此选项禁用缓存目录的所有使用。 不会读取任何文件
从或写入缓存。

--毒药缓存
此选项将缓存目录中的文件视为无效。 不会读取任何文件
来自缓存,但此运行的结果文件仍将写入
缓存。 当 stap 的缓存行为似乎是
行为不端。

- 特权[=斯塔普斯 | =系统 | =开发者]
此选项指示 装订 检查脚本以寻找结构
不允许用于指定的权限级别(请参阅 无特权 USERS).
如果使用任何此类构造,则编译将失败。 如果 斯塔普斯 or 系统 旨在
使用编译服务器时指定(请参阅 --使用服务器),服务器将检查
脚本,如果编译成功,服务器将加密签名
生成的内核模块,证明用户在
指定的权限级别。

If - 特权 没有被指定, -pN 未指定 N < 5,并且
调用用户不是 ,并且不是该组的成员 开发者, 然后 装订
会自动添加合适的 - 特权 选项的选项已经
指定的。

--非特权
这个选项相当于 --特权=stapusr.

--使用服务器[=主机名[:港口] | =IP地址[:港口] | =CERT_SERIAL]
指定用于编译和/或结合使用的编译服务器
--列表服务器--信任服务器 (见下文)。 如果没有提供参数,则
非特权模式下的默认值(请参阅 - 特权) 是选择兼容的服务器
它们被信任为 SSL 对等点和模块签名者并且当前在线。
否则默认选择被信任为 SSL 的兼容服务器
同行,目前在线。 --使用服务器 可以多次指定,其中
如果服务器列表按指定的顺序累积。 服务器可能是
由主机名、IP 地址或证书序列号指定(使用
--列表服务器)。 后者在添加或撤销信任时最常用
服务器(见 --信任服务器 以下)。 如果服务器由主机名或 ip 指定
地址,然后可以指定一个可选的端口号。 这对
访问不在本地网络上的服务器或指定特定的服务器
服务器。

IP 地址可以是 IPv4 或 IPv6 地址。

如果一个特定的 IPv6 地址是本地链路并且存在于多个接口上,
可以通过在地址后附加一个百分比来指定预期的接口
符号 (%) 后跟预期的接口名称。 例如,
"fe80::5eff:35ff:fe07:55ca%eth0".

为了使用 IPv6 地址指定端口号,需要将其括起来
方括号 ([]) 中的 IPv6 地址,以便将端口号与
地址的其余部分。 例如,“[fe80::5eff:35ff:fe07:55ca]:5000”或
"[fe80::5eff:35ff:fe07:55ca%eth0]:5000".

If --使用服务器 没有被指定, -pN 未指定 N < 5,并且
调用用户不是 , 不是该组的成员 开发者,但是是会员
该组织 斯塔普斯, 然后 装订 会自动添加 --使用服务器 到选项
已经指定。

--错误时使用服务器[=|=没有]
指示 stap 使用编译服务器重试编译脚本,如果
本地主机上的编译以某种方式失败,这表明它可能
成功使用服务器。 如果未指定此选项,则默认为 没有。 如果不
提供了参数,则默认值为 . 编译将被重试
可能不会发生的某些类型的错误(例如数据或资源不足)
在编译服务器重新编译期间。 编译服务器将被选中
自动进行重新编译尝试,好像 --使用服务器 被指定为
没有争论。

--列表服务器[=服务器]
显示请求的状态 处理器,在 Moku:Pro 上 处理器 是逗号分隔的
服务器属性列表。 将属性列表组合起来过滤列表
服务器显示。 支持的属性有:

所有 指定所有已知服务器(受信任的 SSL 对等点、受信任的模块签名者、
在线服务器)。

指定
指定使用指定的服务器 --使用服务器.

在线 通过保留有关服务器的信息来过滤输出
目前在线。

信任
通过保留有关受信任服务器的信息来过滤输出
作为 SSL 对等体。

迹象 通过保留有关受信任服务器的信息来过滤输出
作为模块签名者(见 - 特权).

兼容
通过保留有关服务器的信息来过滤输出
与当前的内核版本和架构兼容。

如果没有提供参数,则默认为 指定. 如果没有服务器
指定使用 --使用服务器,然后是默认服务器 --使用服务器 被列为。

需要注意的是 --列表服务器 使用 avahi 守护进程 检测在线服务器的服务。 如果
此服务不可用,然后 --列表服务器 将无法检测到任何 在线
服务器。 为了 --列表服务器 检测侦听 IPv6 地址的服务器,
这些因素包括原料奶的可用性以及达到必要粉末质量水平所需的工艺。 avahi 守护进程 配置文件 /etc/avahi/avahi-daemon.conf 必须包含一个
活跃的“use-ipv6=yes”行。 添加此行后必须重新启动服务
启用 IPv6 的命令。

--信任服务器[=TRUST_规格]
授予或撤销对编译服务器的信任,指定使用 --使用服务器 作为指定
通过 TRUST_SPEC,其中 TRUST_SPEC 是指定信任的逗号分隔列表
将被授予或撤销。 支持的元素有:

SSL 信任指定的服务器作为 SSL 对等体。

迹象 信任指定的服务器作为模块签名者(请参阅 - 特权)。 只有根
可以指定 签字人。

全部用户
为本地主机上的所有用户授予作为 ssl peer 的信任。 默认是
仅授予当前用户作为 ssl 对等方的信任。 信任作为一个模块
签名者始终授予所有用户。 只有 root 可以指定 全部用户.

撤消 撤销指定的信任。 默认是授予它。

无提示
在执行请求之前不提示用户确认
行动。 默认是提示用户确认。

如果没有提供参数,则默认为 SSL. 如果没有指定服务器
运用 --使用服务器,则不会授予或撤销任何信任。

除非 无提示 已指定,会提示用户确认信任
在操作执行之前被授予或撤销。

--转储探针类型
转储支持的探针类型列表并退出。 如果 --特权=stapusr 也是
指定,该列表将仅限于非特权用户可用的探测类型。

--dump-probe-别名
转储在库文件中找到的所有探测器别名的列表并退出。

--转储功能
转储在库文件中找到的所有函数的列表并退出。 还包括他们的
参数和类型。 'unknown' 类型的函数表示一个函数
不返回值。 请注意,并非所有函数/参数类型都可以解析
(这些也显示为“未知”)。 此功能非常占用内存,并且
因此可能无法正常工作 --使用服务器 如果目标服务器强加了 rlimit
在进程内存上(即通过 〜stap-server/.systemtap/rc 配置文件,
请点击 服务器(8))。

--远程 网址
将执行目标设置为给定的主机。 可以重复此选项以定位
多个执行目标。 Passes 1-4 在本地正常完成构建
脚本,然后通过 5 将模块复制到目标并运行它。
可接受的 URL 形式包括:

[用户@]主机名, ssh://[用户@]主机名
此模式使用 ssh,可选择使用与您自己的用户名不匹配的用户名。 如果一个
自定义 ssh_config 文件正在使用中,添加 发送环境 保留
国际化功能。

libvirt://域, libvirt://DOMAIN/LIBVIRT_URI
该模式使用 斯塔维尔 在由管理的域上执行脚本
虚拟机可选地,可以指定 LIBVIRT_URI 以连接到特定的
驱动程序和/或远程主机。 例如连接本地特权
QEMU 驱动,使用:

--remote libvirt://MyDomain/qemu:///system

见页面http://libvirt.org/uri.html> 用于支持的 URI。 另见
斯塔维尔(1) 有关如何为 stap 准备域的更多信息
试探。

Unix:路径
此模式连接到 UNIX 套接字。 这可以与 QEMU virtio 一起使用
用于在正在运行的虚拟机内执行脚本的串行端口。

直接的://
在本地主机上运行的特殊环回模式。

--远程前缀
用“N:”前缀远程输出的每一行,其中N是远程的索引
给定行源自的执行目标。

--下载调试信息[=选项]
启用、禁用或设置自动调试信息下载功能的超时
由 OPTION 指定的 abrt 提供,其中 OPTION 是以下之一:

启用无超时自动下载调试信息。 这是一样的
因为没有提供 OPTION 值 --下载调试信息

没有 明确禁用调试信息的自动下载。 这与
根本不使用该选项。

显示 abrt 输出,并在继续下载之前询问。 不会超时
设置。


将超时指定为正数以停止下载
太长。

--rlimit-as=数字
指定进程的虚拟内存(地址空间)的最大大小,以字节为单位。
如果未指定任何内容,则不施加任何限制。

--r限制CPU=数字
指定 CPU 时间限制,以秒为单位。 如果没有指定,则没有限制
强加的。

--rlimit-nproc=数字
指定可以创建的最大进程数。 如果什么都没有
指定,不施加任何限制。

--rlimit 堆栈=数字
指定进程堆栈的最大大小,以字节为单位。 如果没有指定,
没有任何限制。

--rlimit-fsize=数字
指定进程可以创建的最大文件大小,以字节为单位。 如果没有
指定,不施加任何限制。

--系统根目录=目录
指定目标文件(可执行文件、库等)所在的 sysroot 目录
位于。 和 -r RELEASE, sysroot 将搜索适当的内核
构建目录。 和 -r /目录,但是,sysroot 将不会用于查找
内核构建。

--sysenv=VAR=值
为环境变量提供备用值,其中远程值
系统不同。 假设路径变量(例如 PATH、LD_LIBRARY_PATH)为
相对于提供的目录 --系统根目录,如果提供。

--抑制时间限制
禁用 -DSTP_OVERLOAD 相关选项以及 -DMAXACTION 和 -DMXTRYLOCK。
此选项需要大师模式。

- 运行=模式
设置 pass-5 运行时模式。 有效的选项是 核心 (默认)和 动态。 看
ALTERNATE 运行时间 了解更多信息。

--dyninst
的简写 --运行时=动态.

--保存-uprobes
在需要 SystemTap 构建自己的 uprobes 模块的机器上(内核优先于
到 3.5 版),此选项指示 SystemTap 也保存模块的副本
在当前目录中(首先创建一个新的“uprobes”目录)。

--target-命名空间=PID
允许根据给定的命名空间设置一组目标命名空间
PID 在。这是用于命名空间感知的 Tapset 函数。 如果目标命名空间
未设置,目标默认为 stap 进程的命名空间。

争论


命令行上的任何附加参数都将传递给脚本解析器
代换。 见下文。

SCRIPT 语言


systemtap 脚本语言类似于 AWKC. 有两个主要的最外层
构造:探针和函数。 其中,语句和表达式使用类 C 语言
运算符语法和优先级。

一般 句法
空白被忽略。 支持三种形式的评论:
# ... shell 样式,到行尾,除了 $# 和 @#
// ... C++ 风格,到行尾
/* ... C 风格 ... */
文字是用双引号括起来的字符串(通过通常的 C 转义
带有反斜杠的代码,并将相邻的字符串文字粘在一起,也如在 C 中一样),
或整数(十进制、十六进制或八进制,使用与 C 中相同的表示法)。 全部
字符串的长度限制为某个合理的值(几百字节)。 整数
是 64 位有符号量,尽管解析器也接受(并环绕)值
高于正 2**63。

此外,可以插入在命令行末尾给出的脚本参数。 用
$1 ... $ 对于未加引号的插入, @1 ... @ 用于作为字符串文字插入。 这
可以通过以下方式访问参数数量 $# (作为未引用的数字)或通过 @# (作为一个
引用的数字)。 这些可以在令牌可能开始的任何地方使用,包括在
预处理阶段。 对超出实际给出的参数编号的引用是
错误。

预处理
一个简单的条件预处理阶段作为解析的一部分运行。 一般形式是
类似于条件 ? 经验1 : exp2 三元运算符:

%( 条件 %? 真代币 %)
%( 条件 %? 真代币 %: 假代币 %)

CONDITION 是一个表达式,其格式由其第一个关键字确定,或者
字符串文字比较或数字文字比较。 它也可以由
CONDITIONs 的许多选择和连词(如前一句中的意思)使用 ||
和 && 分别。 但是,尚不支持括号,因此请记住
连接优先于替代很重要。

如果第一部分是标识符 内核_vr or 内核_v 参考内核版本
编号,带(“2.6.13-1.322FC3smp”)或不带(“2.6.13”)发布代码后缀,然后
第二部分是六个标准数字比较运算符之一 <, <=, ==, !=, >,
>=, 第三部分是包含 RPM 样式版本发布的字符串文字
价值。 如果目标内核的版本(如
可选地被覆盖 -r option) 与给定的版本字符串进行比较。 这
比较由 glibc 函数执行 反编译. 作为一种特殊情况,如果
运算符用于简单的相等(==),或不等式 (!=),第三部分包含任何
通配符 (* or ? or [),则表达式被视为通配符(错误)匹配
由评估 匹配.

另一方面,如果第一部分是标识符 参考处理器
架构(由内核构建系统 ARCH/SUBARCH 命名),那么第二部分是
两个字符串比较运算符之一 == or !=, 第三部分是一个字符串
文字来匹配它。 这种比较是通配符(错误)匹配。

类似地,如果第一部分是一个标识符,如 CONFIG_东西 引用内核
配置选项,那么第二部分是 == or !=, 第三部分是一个字符串
用于匹配值的文字(通常为“y”或“m”)。 不存在或未设置的内核
配置选项由空字符串表示。 这个对比也是
通配符(错误)匹配。

如果第一部分是标识符 系统tap_v, 测试参考systemtap
兼容版本,对于带有 - 兼容的 旗。
比较运算符是为 内核_v 正确的操作数是一个版本字符串。
另请参阅下面的弃用部分。

如果第一部分是标识符 systemtap_privilege 权限,测试指的是特权
systemtap 脚本编译的级别。 这是第二部分 == or !=
第三部分是字符串文字,“stapusr”或“stapsys”或“stapdev”。

如果第一部分是标识符 大师模式, 测试指的是 systemtap 脚本是否
用 guru_mode 编译。 这是第二部分 == or !=,第三部分是
数字,1 或 0。

如果第一部分是标识符 运行,测试参考systemtap运行时
模式。 看 ALTERNATE 运行时间 下面是有关运行时的更多信息。 第二部分是
两个字符串比较运算符之一 == or !=, 第三部分是一个字符串
文字来匹配它。 这种比较是通配符(错误)匹配。

否则, CONDITION 应该是两个字符串文字或两个字符串之间的比较
数字文字。 在这种情况下,参数是唯一可用的变量。

TRUE-TOKENS 和 FALSE-TOKENS 是零个或多个通用解析器令牌(可能是
包括嵌套的预处理器条件),如果
条件为真或假。 例如,以下代码会引发解析错误,除非
目标内核版本高于 2.6.5:

%( kernel_v <= "2.6.5" %? **ERROR** %) # 无效的令牌序列

以下代码可能适用于假设的内核版本漂移:

探针内核.函数(
%( kernel_v <= "2.6.12" %? "__mm_do_fault" %:
%( kernel_vr == "2.6.13*smp" %?"do_page_fault" %:
不支持 %) %)
) { /* ... */ }

%( 拱 == "ia64" %?
探针 syscall.vliw = kernel.function("vliw_widget") {}
%)

预处理器
预处理器还支持一个简单的宏工具,在之前作为单独的通道运行
条件预处理

宏使用以下结构定义:

@define 名字 %( 身体 %)
@define NAME(PARAM_1, PARAM_2, ...) %( 身体 %)

宏和宏体中的参数都通过在宏名称前加上前缀来调用
带有@ 符号:

@define foo %( x %)
@define 添加(a,b) %( ((@a)+(@b)) %)

@foo = @add(2,2)

宏扩展当前在条件编译之前在单独的通道中执行。
因此,条件表达式中的 TRUE 和 FALSE 标记都将被宏展开
无论条件如何评估。 这有时会导致错误:

// 以下导致冲突:
%( CONFIG_UTRACE == "y" %?
@define foo %(进程.syscall %)
%:
@define foo %( **错误** %)
%)

// 以下按预期正常工作:
@define 富 %(
%( CONFIG_UTRACE == "y" %? process.syscall %: **ERROR** %)
%)

第一个例子是不正确的,因为两个 @defines 在
有条件地被评估。

通常,宏定义在它出现的文件中是本地的。因此,在
Tapset 不会使其对 Tapset 的用户可用。 公开可用
可以通过在 tapset 搜索路径中包含 .stpm 文件来定义库宏。 这些
文件可能只包含@define 结构,这些结构在所有 Tapset 和
用户脚本。

变数
变量和函数的标识符是一个字母数字序列,可能包括 _
$ 人物。 它们可能不会以纯数字开头,如在 C 中。每个变量都由
默认局部于其中提到它的探针或函数语句块,和
因此它的范围和生命周期仅限于特定的探测或函数调用。

标量变量被隐式输入为字符串或整数。 关联数组
也有一个字符串或整数值,以及一个字符串和/或整数元组作为
钥匙。 这里有一些基本的表达方式。

变量 1 = 5
var2 = "酒吧"
array1 [pid()] = "name" # 单个数字键
array2 ["foo",4,i++] += 5 # string/num/num 键的向量
if (["hello",5,4] in array2) println ("yes") # 成员资格测试

译者执行 类型 推理 在所有标识符上,包括数组索引和
函数参数。 与类型相关的标识符使用不一致表示错误。

变量可以被声明为全局变量,以便它们在所有探测器之间共享并作为
只要整个systemtap会话。 所有全局变量都有一个命名空间,
无论它们位于哪个脚本文件中。 并发访问全局
变量自动用锁保护,参见 安全 AND 保安 对于部分
更多细节。 全局声明可以写在最外层的任何地方,而不是
在一个代码块内。 写入但从未读取的全局变量将被
会话关闭时自动显示。 翻译人员将推断每个值
类型,如果它用作数组,则其键类型。 可选地,标量全局变量可以是
用字符串或数字文字初始化。 以下声明将变量标记为
全球性的。

全球化 无功1, 无功2, 变量 3=4

全局变量也可以设置为模块选项。 可以通过使用 -G 来做到这一点
选项,或者模块必须首先使用 stap -p4 编译。 全局变量可以是
在 stap -p4 生成的模块上调用 staprun 时在命令行上设置。 看
斯塔普伦(8) 了解更多信息。

数组的大小受 MAXMAPENTRIES 变量的限制——请参阅 安全 AND 保安
部分了解详情。 可选地,全局数组可以声明为最大大小
方括号,仅覆盖该数组的 MAXMAPENTRIES。 请注意,这并不表示
数组的键类型,只是大小。

全球化 小数组[10], 正常数组, 大数组[50000]

数组可以配置为使用“%”后缀进行包装。 这会导致旧元素
如果插入的元素多于数组可以容纳的元素,则将被覆盖。 这对两者都有效
关联和统计类型数组。

全球化 包裹阵列1%[10], 包裹阵列2%

许多类型的探测点提供上下文变量,这些变量是运行时值,安全地
从被探测的内核或用户空间程序中提取。 这些以
$ 特点。 中的上下文变量部分 探针(3stap) 列出可用的内容
对于每种类型的探测点。 这些上下文变量变成普通的字符串或数字
标量一旦存储在普通脚本变量中。 参见 TYPECASTING 部分
下面是关于如何将它们转回类型化指针以作为上下文进一步处理
变量。

声明
语句启用过程控制流。 它们可能出现在函数和探针中
处理程序。 响应任何单个探测事件而执行的语句总数
仅限于由翻译的 C 代码中的宏定义的某个数字,并且在
1000附近。

EXP 执行字符串或整数值表达式并丢弃该值。

{ STMT1 STMT2 ... }
依次执行此块中的每个语句。 请注意分隔符或
语句之间通常不需要终止符。

; 空语句,什么都不做。 它可用作之间的可选分隔符
改进语法错误检测和处理某些语法的语句
歧义。

if (EXP)STMT1 [ 其他 STMT2]
将整数值 EXP 与零进行比较。 执行第一个(非零)或第二个 STMT
(零)。

(经验) STMT
当整数值 EXP 计算为非零时,执行 STMT。

HPMC胶囊 (EXP1;EXP2;EXP3)STMT
执行 EXP1 作为初始化。 当 EXP2 不为零时,执行 STMT,然后
迭代表达式 EXP3。

的foreach (无功 in 大批 [ 限制 经验]) STMT
循环命名全局数组的每个元素,将当前键分配给 VAR。
不能在语句中修改数组。 通过添加单个 + or -
VAR 或 ARRAY 标识符之后的运算符,迭代将在
按升序或降序索引或值排序。 如果数组包含
统计聚合,添加所需的 @操作员 在 ARRAY 标识符之间
+ or - 将指定排序聚合函数。 查看统计数据
下面的部分是可用的。 默认是 @数数. 使用可选 限制
关键字将循环迭代次数限制为 EXP 次。 EXP 被评估一次
在循环的开始。

的foreach ([VAR1, VAR2, ...] in 大批 [ 限制 经验]) STMT
同上,当数组用键元组索引时使用。 一个排序
后缀最多可用于一个 VAR 或 ARRAY 标识符。

的foreach ([VAR1, VAR2, ...] in 数组 [INDEX1, INDEX2, ...] [ 限制 经验]) STMT
与上面相同,其中迭代仅限于数组中的元素,其中键
匹配指定的索引值。 符号 * 可用于指定索引和
将被视为通配符。

的foreach (值 = VAR in 大批 [ 限制 经验]) STMT
foreach 的这个变体在每次迭代时将当前值保存到 VALUE 中,因此它是
与 ARRAY[VAR] 相同。 这也适用于键元组。 排序后缀
VALUE 与 ARRAY 具有相同的效果。

的foreach (值 = VAR in 数组 [INDEX1, INDEX2, ...] [ 限制 经验]) STMT
与上面相同,其中迭代仅限于数组中的元素,其中键
匹配指定的索引值。 符号 * 可用于指定索引和
将被视为通配符。

打破, 继续
退出或迭代最里面的嵌套循环 ( or HPMC胶囊 or 的foreach) 陈述。

回报 进出口
从封闭函数返回 EXP 值。 如果函数的值不被采用
任何地方,则不需要 return 语句,该函数将有一个
没有返回值的特殊“未知”类型。

下页 现在从封闭的探针处理程序返回。 这在探测中特别有用
应用事件过滤谓词的别名。

尝试 {STMT1} 捕捉 {STMT2}
运行第一个块中的语句。 在出现任何运行时错误时,中止 STMT1 并
开始执行STMT2。 STMT2 中的任何错误都将传播到外部 try/catch
块,如果有的话。

尝试 {STMT1} 捕捉(VAR) {STMT2}
同上,加上将错误信息分配给字符串标量变量 VAR。

删除 数组[索引 1,索引 2,...]
从 ARRAY 中删除由索引元组指定的元素。 如果索引元组
包含一个 * 代替索引,* 被视为通配符和所有元素
与索引元组匹配的键将从 ARRAY 中删除。 值不会
不再可用,后续迭代将不会报告该元素。 这是
删除不存在的元素不是错误。

删除 ARRAY
从 ARRAY 中删除所有元素。

删除 标量
删除 SCALAR 的值。 整数和字符串被清除为 0 和 ""
分别,而统计信息被重置为初始空状态。

表情
Systemtap 支持许多具有相同通用语法、语义和
C 和 awk 中的优先级。 算术是按照典型的 C 规则执行的签名
整数。 检测到被零除或溢出并导致错误。

二元数字运算符
* / % + - >> << & ^ | && ||

二元串运算符
. (字符串连接)

数字赋值运算符
= *= /= %= += -= >> = << = &= ^= |=

字符串赋值运算符
= .=

一元数字运算符
+ - ! ~ ++ --

二进制数字、字符串比较或正则表达式匹配运算符
< > <= >= == != =~ !~

三元运算符
COND ? 经验1 : 经验2

分组运算符
( EXP )

函数调用
fn ([ 参数 1,参数 2,... ])

数组成员检查
EXP in 排列
[经验1, 经验2, ...] in 排列
[*, *, ... ]in 排列

定期 表达 匹配
脚本语言支持正则表达式匹配。 基本语法是
如下:

EXP =~ 正则表达式
EXP !~ 正则表达式

(第一个操作数必须是计算结果为字符串的表达式;第二个操作数必须
是包含语法上有效的正则表达式的字符串文字。)

正则表达式语法支持 POSIX Extended Regular 的大部分功能
表达式,除了子表达式重用 ("\1") 功能。 捕捉能力
并提取匹配的字符串和子表达式的内容尚未被
已实施。

问题
脚本语言中的主要结构标识探针。 探针相关摘要
带有语句块(“探测处理程序”)的事件,当这些事件中的任何一个时要执行
事件发生。 一般语法如下:

探测器 探测点 [, 探测点] { [STMT...] }
探测器 探测点 [, 探测点] if (条件) { [STMT...] }

事件以称为“探测点”的特殊语法指定。 有几种
转换器定义的各种探测点,tapset 脚本可以进一步定义
使用别名的。 探测点可以通配、分组或优先列出
序列,或声明为可选。 关于探测点语法和语义的更多细节是
列在上面 探针(3stap) 手册页。

探测处理程序相对于每个事件的上下文进行解释。 对于活动
与内核代码相关联,此上下文可能包括 变量 定义在 资源
在那个地方。 这些“上下文变量”作为变量呈现给脚本
名称以“$”为前缀。 只有在内核编译器保留的情况下才能访问它们
尽管进行了优化。 这与调试器用户在以下情况下面临的约束相同
使用优化的代码。 此外,对象必须存在于分页内存中
systemtap 探测处理程序执行的那一刻,因为 systemtap 不能导致
(抑制)任何额外的分页。 某些探针类型的上下文非常少。 见
探针(3stap) 手册页以查看每种可用的上下文变量的种类
探测点。

探头可以装饰有 武装 流程条件, 由一个简单的布尔值组成
只读全局脚本变量上的表达式。 解除武装时(条件评估为
false),某些探测类型会减少或消除它们的运行时开销。 当一个武装
条件评估为真,探测器将 或很快需要, 重新武装,他们的探测处理程序将
随着事件的发生,开始被调用。 (在布防过程中可能会丢失一些事件
间隔。 如果这是不可接受的,请不要对这些探头使用激活条件。)

可以使用“别名”来定义新的探测点。 探测点别名看起来类似于
探针定义,但不是在给定点激活探针,它只是定义一个
新探测点名称作为现有探测点的别名。 有两种类型的别名,即
由“=”和“+=”标识的序言风格和尾声风格


对于序言风格的别名,别名定义后面的语句块是
作为序言隐式添加到任何引用别名的探测中。 而对于
结尾样式别名,别名定义后面的语句块是隐式的
作为结尾添加到任何引用别名的探测中。 例如:

探针 syscall.read = kernel.function("sys_read") {
菲尔兹 = $fd
if (execname() == "init") next # 跳过其余的探测
}

定义一个新的探测点 系统调用.read, 扩展为 内核函数(“sys_read”),
给定的语句作为序言,这对于预定义一些变量很有用
别名用户和/或完全基于某些条件跳过探测处理。 和

探针 syscall.read += kernel.function("sys_read") {
如果 (tracethis) println ($fd)
}

用给定的语句定义一个新的探测点作为结尾,这很有用
基于别名用户设置或遗留的变量的操作。 请注意,在
每种情况下,别名处理程序块中的语句都被正常处理,以便
在那里分配的变量仅构成初始化,而不是宏替换。

别名就像内置探针类型一样使用。

探针 syscall.read {
printf("读取 fd=%d\n", fildes)
如果(fildes > 10)tracethis = 1
}

职能
Systemtap 脚本可以定义子程序来分解常见的工作。 函数取任何
标量(整数或字符串)参数的数量,并且必须返回单个标量(整数
或字符串)。 示例函数声明如下所示:

函数 thisfn (arg1, arg2) {
返回 arg1 + arg2
}

请注意一般没有类型声明,而是由
翻译。 但是,如果需要,函数定义可以包含显式类型
其返回值和/或其参数的声明。 这对以下方面特别有帮助
嵌入式 C 函数。 在下面的例子中,类型推断引擎只需要推断
type arg2 的类型(字符串)。

函数 thatfn:string (arg1:long, arg2) {
返回 sprint(arg1) 。 arg2
}

函数可以递归调用他人或自己,直到一个固定的嵌套限制。 这个
limit 由翻译后的 C 代码中的宏定义,在 10 附近。

染印
有一组由翻译器特别处理的函数名称。 他们
以更方便的方式打印到标准 systemtap 输出流的格式值
道路。 这 短跑* 变体返回格式化的字符串而不是打印它。

打印, 短跑
打印一个或多个任何类型的值,直接连接在一起。

打印, 打印
打印值如 打印短跑, 但也要附加一个换行符。

印刷的, 冲刺
取一个字符串分隔符和两个或多个任意类型的值,并打印这些值
插入分隔符。 分隔符必须是文字字符串常量。

打印输入, 冲刺蛋白
使用分隔符打印值,例如 印刷的冲刺, 但也要附加一个换行符。

的printf, 冲刺
取一个格式化字符串和一些对应类型的值,并打印
商场。 格式必须是文字字符串常量。

这个 的printf 类似于 C 的格式化指令,除了它们是完全类型的
由翻译人员检查:

%b 写入给定值的二进制 blob,而不是 ASCII 文本。 宽度
说明符确定要写入的字节数; 有效的说明符是 %b
%1b %2b %4b %8b。 默认 (%b) 为 8 个字节。

%c 字符。

%d,%i 有符号十进制。

%m 在给定地址安全读取内核内存,输出其内容。 这
可选的精度说明符(不是字段宽度)决定了
要读取的字节 - 默认为 1 个字节。 %10.4m 打印 4 个字节的内存
10 个字符宽的字段。

%M 与 %m 相同,但以十六进制输出。 输出的最小尺寸是
将可选精度说明符加倍 - 默认为 1 个字节(2 个十六进制字符)。
%10.4M 将内存的 4 个字节打印为 8 个十六进制字符
10 个字符宽的字段。

%o 无符号八进制。

%p 无符号指针地址。

%s 字符串。

%u 无符号十进制。

%x 无符号十六进制值,全部小写。

%X 无符号十六进制值,全部大写。

%% 写一个 %。

这个 # 标志选择替代形式。 对于八进制,此前缀为 0。对于十六进制,此
前缀 0x 或 0X,视情况而定。 对于字符,这会转义非打印值
带有类似 C 的转义或原始八进制。

例子:

a = "alice", b = "bob", p = 0x1234abcd, i = 123, j = -1, id[a] = 1234, id[b] = 4567
打印(“你好”)
打印:你好
打印(b)
打印:鲍勃\n
println(a . " 是 " . 短跑(16))
印刷品:爱丽丝 16 岁
foreach (id 中的名字) printdln("|", strlen(name), name, id[name])
打印数:5|alice|1234\n3|bob|4567
printf("%c 是 %s; %x 或 %X 或 %p; %d 或 %u\n",97,a,p,p,p,j,j)
打印:a 是 alice; 1234abcd 或 1234ABCD 或 0x1234abcd; -1 或 18446744073709551615\n
printf("地址 %p 处的内核缓冲区的 2 个字节:%2m", p, p)
打印:地址 2x0abcd 处的 1234 字节内核缓冲区:
printf("%4b", p)
打印(这些值作为二进制数据):0x1234abcd
printf("%#o %#x %#X\n", 1, 2, 3)
打印:01 0x2 0X3
printf("%#c %#c %#c\n", 0, 9, 42)
打印:\000 \t *

统计
通常希望以一种避免惩罚的方式来收集统计数据。
反复独占锁定这些数字被放入的全局变量。
Systemtap 提供了一种使用特殊运算符来累积值的解决方案,以及几个
用于提取统计聚合的伪函数。

聚合运算符是 <<, 类似于赋值或 C++ 输出流
手术。 左操作数指定标量或数组索引左值,必须是
宣布为全球。 右操作数是一个数值表达式。 意思很直观:
将给定的数字添加到要计算的数字堆中。 (具体名单
要收集的统计数据由提取函数单独给出。)

富<<< 1
stats[pid()] <<< memsize

提取功能也很特别。 对于不同提取的每次出现
在给定标识符上运行的函数,翻译器安排计算一组
满足它的统计数据。 统计系统因此是“按需”的。 每次执行
提取函数的作用导致在那一刻计算所有的聚合
处理器。

这是提取器功能集。 每个的第一个参数是相同的样式
左值用于累加操作的左侧。 这 @计数(v), @总和(v),
@分钟(v), @最大(v), @平均(v) 提取器函数计算
所有累积值的数量/总数/最小值/最大值/平均值。 结果值是
所有简单的整数。 可以对包含聚合的数组进行排序和迭代。 见
的foreach 构建上面。

直方图也可用,但更复杂,因为它们有一个向量而不是
比标量值。 @hist_linear(v,开始,停止,间隔) 表示来自的线性直方图
通过“间隔”的增量“开始”到“停止”。 间隔必须为正。 相似地,
@hist_log(v) 表示以 2 为底的对数直方图。 打印直方图
打印 函数系列将直方图对象呈现为表格“ASCII 艺术”条形图。

探测计时器.profile {
x[1] <<< pid()
x[2] <<< uid()
y <<< tid()
}
global x // 一个包含聚合的数组
global y // 一个标量
探针端{
foreach ([i] in x @count+) {
printf ("x[%d]: avg %d = sum %d / count %d\n",
i、@avg(x[i])、@sum(x[i])、@count(x[i]))
println (@hist_log(x[i]))
}
println ("y:")
println (@hist_log(y))
}

打字机
一旦一个指针(见上下文变量部分 探针(3stap)) 已保存
转换成脚本整数变量,翻译器丢失了必要的类型信息
从该指针访问成员。 使用 @投掷() 接线员告诉译员如何
将数字解释为类型化指针。

@cast(p, "type_name"[, "module"])->member

这将解释 p 作为指向名为的结构/联合的指针 类型名称 并取消引用
会员 价值。 更远 ->子域 可以附加表达式以取消引用更多级别。
注意:相同的解引用运算符 -> 用于指直接遏制或
指针间接。 Systemtap 会自动确定哪个。 可选的 模块 告诉
翻译器在哪里查找有关该类型的信息。 多个模块可能是
指定为一个列表 : 分隔符。 如果未指定模块,则默认
要么是用于矮探测器的探测器模块,要么是用于函数和所有其他的“内核”
探针类型。

翻译器可以创建自己的模块,其中包含来自头文件的类型信息。
尖括号,以防正常调试信息不​​可用。 对于内核头文件,添加前缀
使用“内核”来使用适当的构建系统。 所有其他标头都是用
默认 GCC 参数到用户模块中。 可以按顺序指定多个标题
解决相互依赖。

@cast(tv, "timeval", " ")->tv_sec
@cast(task, "task_struct", "内核")->tgid
@cast(任务,“task_struct”,
“核心")->fs->umask

获得的价值 @投掷 可能是漂亮的印刷品 $$$ 后缀运算符,相同
的上下文变量部分中描述的方式 探针(3stap) 手册页。

在大师模式下,翻译器还将允许脚本为成员分配新值
类型转换的指针。

类型转换在以下情况下也很有用 无效* 其类型可在以下位置确定的成员
运行。

探针 foo {
如果 ($var->type == 1) {
value = @cast($var->data, "type1")->bar
} {
value = @cast($var->data, "type2")->baz
}
打印(值)
}

嵌入式 C
在大师模式下,翻译器接受脚本顶层的嵌入代码。
此类代码包含在 %{%} 标记,并逐字转录,没有
以某种顺序分析生成的 C 代码的顶层。 在最外面
级别,这可能有助于添加 的#include 说明,以及任何辅助定义
由其他嵌入代码使用。

另一个允许嵌入代码的地方是作为函数体。 在这种情况下,
脚本语言体完全被一段 C 代码所取代 %{
%} 标记。 这个 C 代码可以做任何合理和安全的事情。 有许多
对原子性、并发性、资源的未记录但复杂的安全约束
消耗和运行时间限制,所以这是一种先进的技术。

为输入和输出值预留的内存位置可使用
STAP_ARG_*STAP_RETVALUE. 错误可以通过 STAP_ERROR 发出信号。 输出可能
用 STAP_PRINTF 写入。 该函数可能会使用 STAP_RETURN 提前返回。 这里有
一些例子:

函数 integer_ops (val) %{
STAP_PRINTF("%d\n", STAP_ARG_val);
STAP_RETVALUE = STAP_ARG_val + 1;
如果(STAP_RETVALUE == 4)
STAP_ERROR("猜测错误:%d", (int) STAP_RETVALUE);
如果(STAP_RETVALUE == 3)
返回(0);
STAP_RETVALUE ++;
%}
函数 string_ops (val) %{
strlcpy(STAP_RETVALUE,STAP_ARG_val,MAXSTRINGLEN);
strlcat (STAP_RETVALUE, "one", MAXSTRINGLEN);
如果(strcmp(STAP_RETVALUE,“三二一”))
STAP_RETURN("参数应该是三二二-");
%}
函数 no_ops() %{
STAP_RETURN(); /* 没有返回值的函数推断 */
%}

函数参数和返回值类型必须由翻译器从
呼叫站点以使其正常工作。 用户应检查生成的 C 代码
普通的脚本语言函数,以便编写兼容的嵌入式 C 函数。

允许嵌入代码的最后一个地方是作为表达式右值。 在这种情况下,
之间的 C 代码 %{%} 标记被解释为普通表达式
价值。 它被假定为一个正常的 64 位有符号数,除非标记 /* 绳子 */
包括在内,在这种情况下,它被视为一个字符串。

函数 add_one (val) {
返回值 + %{ 1 %}
}
函数 add_string_two (val) {
返回值。 %{ /* 字符串 */ "两个" %}
}

嵌入式 C 代码可能包含用于声明优化和安全属性的标记。

/* */
意味着 C 代码没有副作用,如果它的值可以完全省略
不被脚本代码使用。

/* 稳定 */
意味着 C 代码始终具有相同的值(在任何给定的探测处理程序中
调用),所以重复的调用可能会被记忆值自动替换。
这样的函数必须不带参数,并且 .

/* 没有特权的 */
意味着 C 代码非常安全,即使是非特权用户也可以使用
它。

/* myproc-非特权 */
意味着 C 代码非常安全,即使是非特权用户也可以使用
它,前提是当前探测的目标在用户自己的进程内。

/* 领袖 */
意味着 C 代码是如此不安全,以至于 systemtap 用户必须指定 -g (古鲁
模式)来使用它。

/* 完好无损 */
在嵌入式 C 函数中,意味着旧的(1.8 之前的)参数访问语法
应该在函数内部可用。 因此,除了 STAP_ARG_foo
STAP_RETVALUE 一个可以使用 这-> foo这->__重估 分别在里面
功能。 这对于快速迁移为 SystemTap 编写的代码很有用
1.7 及更早版本。

/* 未修改的fnargs */
在嵌入式 C 函数中,意味着不修改函数参数
在函数体内。

/* 绳子 */
仅在嵌入式 C 表达式中,意味着该表达式具有 常量 坦克 * 键入和
应该被视为字符串值,而不是默认的长数字。

内置
一组内置的探测点别名由安装在
指定的目录 步行者(7) 手册页。 功能描述在
探针(3stap) 手册页。

处理


翻译器通过解析给定的输入脚本和所有脚本(文件
命名 *.stp) 在 tapset 目录中找到。 列出的目录 -I 在处理
序列,每个都以“大师模式”处理。 每个目录下有若干子目录
也被搜索。 这些子目录来自选定的内核版本(
-R 选项),以允许更多特定于内核版本的脚本覆盖更少
具体的。 例如,对于内核版本 2.6.12-23.FC3 以下模式
将按顺序搜索: 2.6.12-23.FC3/*.stp, 2.6.12/*.stp, 2.6/*.stp,最后
*.stp. 在第 1 轮之后停止翻译器会导致它打印解析树。

在第 2 轮中,翻译器分析输入脚本以解析符号和类型。
对内部未解析的变量、函数和探测别名的引用是
通过搜索解析的 tapset 脚本文件来满足。 如果有任何 Tapset 脚本文件
被选中是因为它定义了一个未解析的符号,那么整个文件都是
添加到翻译器的解析队列中。 这个过程不断迭代,直到所有的符号都
已解决并选择了 Tapset 脚本文件的子集。

接下来,所有探测点描述都根据支持的广泛多样性进行验证。
翻译。 参考代码位置的探测点(“同步探测点”)
需要安装适当的内核调试信息。 在相关的
探测处理程序、目标端变量(名称以“$”开头)被找到并具有
它们的运行时位置被解码。

接下来,分析所有探针和函数以寻找优化机会,以便
删除没有用处和副作用的变量、表达式和函数。
假定嵌入式 C 函数具有副作用,除非它们包含魔法字符串
/* */. 由于这种优化可以隐藏潜在的代码错误,例如类型不匹配
或无效的 $context 变量,有时禁用优化可能很有用
-u 选项。

最后,所有变量、函数、参数、数组和索引类型都从
上下文(文字和运算符)。 在第 2 遍后停止翻译器会导致它列出
所有探测器、函数和变量,以及所有推断的类型。 任何不一致
或未解析的类型会导致错误。

在第 3 轮中,翻译器编写代表所有选定脚本的动作的 C 代码
文件,并创建一个 生成文件 将其构建到内核对象中。 这些文件被放置
进入一个临时目录。 此时停止翻译器会导致它打印
C 文件的内容。

在第 4 轮中,翻译器调用 Linux 内核构建系统来创建实际的
内核目标文件。 这涉及运行 使 在临时目录中,并且需要一个
内核模块构建系统(头文件、配置和 Makefile)要安装在通常的
现场 /lib/模块/版本/构建. 在pass 4之后停止翻译是最后的机会
在运行内核对象之前。 如果要存档文件,这可能很有用。

在pass 5中,翻译器调用systemtap辅助程序 斯塔普伦 程序的
给定的内核对象。 这个程序安排加载模块然后与它通信,
将跟踪数据从内核复制到临时文件中,直到用户发送中断
信号。 探测处理程序遇到的任何运行时错误,例如用完
内存,除以零,超出嵌套或运行时限制,导致软错误
指示。 超过所有后续探测的 MAXERRORS 块的软错误(除了
错误处理探测),并终止会话。 最后, 斯塔普伦 卸载模块,
并清理。

不正常 终止
应该避免强行杀死 stap 进程,例如使用 SIGKILL,因为
stapio 进程(stap 进程的子进程)和加载的模块可能会留下
在系统上运行。 如果发生这种情况,请将 SIGTERM 或 SIGINT 发送到任何剩余的 stapio
进程,然后使用 rmmod 卸载 systemtap 模块。

示例


查看 镫骨(3stap) 手册页,用于简要收集样本或大量样本
在 systemtap 文档/测试套件目录下安装了示例。 看
步行者(7stap) 获取这些在系统上的可能位置。

缓存


systemtap 转换器缓存 pass 3 输出(生成的 C 代码)和 pass 4
如果第 4 步成功完成,则输出(编译后的内核模块)。 这个缓存的输出
如果假设存在相同的条件(相同的
内核版本、相同的 systemtap 版本等)。 缓存文件存储在
$SYSTEMTAP_DIR/缓存 目录。 缓存可以通过拥有文件来限制 缓存MB限制
放置在缓存目录(如上所示)中,只包含一个 ASCII 整数表示
缓存不应超过多少 MiB。 如果没有此文件,则默认为
创建时限制设置为 256MiB。 这是一个“软”限制,因为缓存将
如果超过缓存清理间隔,则在添加新条目后清理,因此总计
缓存大小可能会暂时超过此限制。 可以通过使
文件 缓存清理间隔时间 放置在仅包含一个缓存目录(如上所示)中
ASCII 整数,表示以秒为单位的间隔。 在没有这个文件的情况下,默认
将创建间隔设置为 300 秒。

安全 AND 保安


Systemtap 可用作强大的管理工具。 它可以暴露内核内部
数据结构和潜在的私人用户信息。 (在 动态 运行时模式,这个
事实并非如此,请参阅 ALTERNATE 运行时间 以下部分。)

翻译器在编译期间断言许多安全约束,在运行期间断言更多
时间。 它旨在确保没有处理程序可以运行很长时间,分配无限
内存,执行不安全的操作,或在无意中干扰系统。 用途
的脚本全局变量会根据需要自动读/写锁定,以保护
防止并发探测处理程序的操纵。 (通过超时检测死锁。
使用 -t 标志以接收过度锁争用的报告。)
因此脚本通常是 安全. 大师模式 -g 选项允许管理员
绕过大多数允许侵入性或状态改变操作的安全措施,
嵌入式 C 代码,并增加了心烦意乱的风险。 默认情况下,过载预防是
为所有模块打开。 如果您想禁用过载处理,请使用
--抑制时间限制 选项。

在运行时捕获的错误通常会导致干净的脚本关闭和 pass-5
错误信息。 这 --suppress-handler-错误 选项让脚本容忍软错误
无需关机。

PERMISSIONS
对于正常的 linux-kernel-module 运行时,要运行内核对象 systemtap 构建,
用户必须是以下之一:

· root用户;

· 成员之一 开发者斯塔普斯 组;

· 成员之一 系统斯塔普斯 团体; 或者

· 成员之一 斯塔普斯 组。

root 用户或同时是两者成员的用户 开发者斯塔普斯 组可以建立
并运行任何 systemtap 脚本。

既是两个成员的用户 系统斯塔普斯 组只能使用预建
以下条件下的模块:

· 模块已由受信任的签名者签名。 受信任的签名者通常是 systemtap
编译服务器签署模块时 - 特权 选项由
客户。 见 服务器(8) 手册页了解更多信息。

· 该模块是使用 --特权=stapsys 或者 --特权=stapusr 选项​​。

成员只有 斯塔普斯 组只能使用以下预建模块
条件:

· 该模块位于/lib/modules/VERSION/systemtap 目录中。 这个目录
必须由 root 拥有并且不可全局写入。

or

· 模块已由受信任的签名者签名。 受信任的签名者通常是 systemtap
编译服务器签署模块时 - 特权 选项由
客户。 见 服务器(8) 手册页了解更多信息。

· 该模块是使用--privilege=stapusr 选项构建的。

生成的内核模块 装订 程序由 斯塔普伦 程序。 后者
是 Systemtap 包的一部分,专用于模块加载和卸载(但仅在
白区),以及内核到用户的数据传输。 自从 斯塔普伦 不执行任何
对给定的内核对象进行额外的安全检查,对于一个
系统管理员将不受信任的用户添加到 开发者 or 斯塔普斯 组。

安全启动
如果当前系统在 UEFI 固件中开启了 SecureBoot,则所有内核模块
必须签名。 (某些内核可能允许在使用
SysRq-X 等密钥序列,无需对模块进行签名。) systemtap
编译服务器可以使用与它共同的 MOK(机器所有者密钥)对模块进行签名
一个客户系统。 有关更多详细信息,请参阅以下 wiki 页面:

https://sourceware.org/systemtap/wiki/SecureBoot

RESOURCE 极限
许多资源使用限制是由生成的 C 代码中的宏设置的。 这些可能是
被覆盖 -D 旗帜。 其中选择如下:

最大嵌套
嵌套函数调用的最大数量。 默认由脚本分析确定,
为递归脚本增加了 10 个插槽。

最大字符串
字符串的最大长度,默认 128。

最大锁
在声明之前等待锁定全局变量的最大迭代次数
可能出现死锁并跳过探测,默认为 1000。

最大行动
在任何单次探测命中期间要执行的最大语句数(使用
中断禁用),默认 1000。请注意,对于直通探测处理程序
缺少循环或递归,由于优化,此参数可能会被解释
太保守了。

MAXACTION_INTERRUPTIBLE
在任何单个探测命中期间要执行的最大语句数是
在启用中断的情况下执行(例如开始/结束探测),默认(MAXACTION *
10)。

最大回溯
stap 运行时将处理的最大堆栈帧数
由 [u]context-unwind.stp 中的回溯函数生成的展开器
Tapsets,默认 20。

最大地图
任何单个全局数组中的默认最大行数,默认为 2048。
可以使用更大或更小的限制来声明单个数组:

全局大[10000],小[5]

或表示为 % 使它们自动环绕。

最大错误数
触发退出前的最大软错误数,默认为 0,表示
第一个错误将退出脚本。 请注意,与
--suppress-handler-错误 选项,不强制执行此限制。

最大跳过
触发退出前跳过的最大探测数,默认为 100。正在运行
systemtap with -t (timing) 模式提供了更多关于跳过的探测的细节。 随着
默认 -DINTERRUPTIBLE=1 设置,由于可重入而跳过的探测器不是
针对此限制累积。 请注意,与 --suppress-handler-错误
选项,不强制执行此限制。

最小堆栈空间
运行探测处理程序所需的最小可用内核堆栈字节数,
默认 1024。这个数字应该足够大以供探测处理程序自己使用
需求,加上安全边际。

最大探头
并发武装的用户空间探测器(uprobes)的最大数量,有点默认
大于脚本中命名的用户空间探测点的数量。 这个池
需要可能很大,因为单个 uprobe 对象(大约 64 字节
每个) 分配给每个匹配的脚本级探测的每个进程。

STP_MAXMEMORY
systemtap 模块应该使用的最大内存量(以千字节为单位),
默认无限制。 内存大小包括模块本身的大小,加上
任何额外的分配。 这仅跟踪 systemtap 的直接分配
运行。 这不会跟踪间接分配(如 kprobes/uprobes/etc 所做的那样。
内部)。

STP_OVEROAD_THRESHOLD、STP_OVERLOAD_INTERVAL
每个给定间隔在任何 cpu 上的探测器中花费的最大机器周期数,
在声明重载条件并且脚本关闭之前。 默认值
分别是 500 亿和 1 亿,从而将 stap 脚本 cpu 消耗限制在
50%。

STP_PROCFS_BUFSIZE
procfs 探针读取缓冲区的大小(以字节为单位)。 默认为 最大字符串。 这
可以使用 procfs 读取探针在每个 procfs 文件的基础上覆盖值
.maxsize(最大尺寸) 参数。

对于在任何中断路径上包含探测器的脚本,那些
中断可能发生在另一个探测处理程序的中间。 中断中的探测
在这种情况下将跳过处理程序以避免重入。 要解决此问题,
使用选项执行 stap -可中断=0 屏蔽整个探测过程中的中断
处理程序。 这确实给探测器增加了一些额外的开销,但它可能会阻止重入
对于常见的问题案例。 但是,在 NMI 处理程序和 stap 的调用路径中进行探测
由于重入,运行时可能仍会被跳过。

多个脚本可以同时将数据写入中继缓冲区。 主机脚本提供
用于访问其中继缓冲区到来宾脚本的接口。 然后,输出
来宾被合并到主机的输出中。 要以主机身份运行脚本,请执行 stap
- -DRELAYHOST[=名称] 选项。 该 姓名 在多个主机中识别您的主机脚本。
在运行主机时,执行 stap with -DRELAYGUEST[=姓名] 将访客脚本添加到
主持人。 请注意,您必须先卸载访客,然后才能卸载主机。 如果有客人
连接到主机,卸载主机将失败。

万一出现问题 装订 or 斯塔普伦 在探测已经开始之后
运行,可以安全地杀死两个用户进程,并删除活动的探针内核
模块与 rmmod. 任何挂起的跟踪消息都可能丢失。

无特权 USERS


Systemtap 暴露内核内部数据结构和潜在的私有用户
信息。 因此,使用 systemtap 的全部功能仅限于 root
以及属于 stapdev 和 stapusr 组成员的用户。

然而,一组受限制的 systemtap 功能可以提供给受信任的,
非特权用户。 这些用户只是 stapusr 组的成员,或者是
组 stapusr 和 stapsys。 这些用户可以加载 systemtap 模块
由受信任的 systemtap 编译服务器编译和认证。 见说明
选项 - 特权--使用服务器。 看 自述文件.unprivileged 在 systemtap 源代码中
有关设置可信编译服务器的信息。

限制执行的时间 --特权=stapsys 指定旨在防止
非特权用户来自:

· 恶意破坏系统。

限制执行的时间 --特权=stapusr 指定旨在防止
非特权用户来自:

· 恶意破坏系统。

· 获得通常无法获得的信息
非特权用户。

· 破坏系统其他用户拥有的进程的性能。
系统的一些开销通常是不可避免的,因为没有特权的
用户的探测将在适当的时间被触发。 我们想要什么
避免有针对性地中断另一个用户的进程,这不会
通常可以由非特权用户使用。

探测 限制
stapusr 和 stapsys 组的成员可以使用所有探测点。

只有 stapusr 组的成员只能使用以下探测器:

·开始,开始(n)

· 结束,结束(n)

· 错误(n)

· 绝不

· process.*,其中目标进程归用户所有。

· 计时器。{jiffies,s,sec,ms,msec,us,usec,ns,nsec}(n)*

·定时器.hz(n)

SCRIPT 语言 限制
所有非特权用户都无法使用以下脚本语言功能:

· Guru Mode (-g) 选项启用的任何功能。

· 嵌入式C 代码。

运行 限制
以下运行时限制适用于所有非特权用户:

· 只有默认的运行时代码(见 -R) 可能用过了。

仅对 stapusr 组的成员施加了其他限制:

· 不允许探查其他用户拥有的进程。

· 不允许访问内核内存(读和写)。

指挥 LINE OPTION 限制
某些命令行选项提供对并非所有人都可用的功能的访问
非特权用户:

· 不能指定-g。

· 编译服务器客户端不能使用以下选项:

-a、-B、-D、-I、-r、-R

环境 限制
不得为所有非特权用户设置以下环境变量:

SYSTEMTAP_RUNTIME
SYSTEMTAP_TAPSET
SYSTEMTAP_DEBUGINFO_PATH

水龙头组 限制
一般而言,tapset 功能仅对 stapusr 组的成员可用
不要收集以该用户权限运行的普通程序的信息
将被拒绝访问。

有两类非特权 Tapset 函数。 第一类包括
对所有用户无条件可用的效用函数; 这些包括这样的
事情如:

中央处理器:长()
出口 ()
str_replace:字符串(prnt_str:字符串,srch_str:字符串,rplc_str:字符串)

第二类包括所谓的 myproc-非特权 功能,只能
在他们自己的流程中收集信息。 希望使用这些功能的脚本
必须测试 tapset 函数的结果 is_myproc 并且仅在以下情况下调用这些函数
结果是 1。如果这些函数中的任何一个被调用,脚本将立即退出
进程内的探测器中的非特权用户,该用户不属于该用户。
示例 myproc-非特权 功能包括:

print_usyms(stk:字符串)
user_int:long(地址:long)
用户名:字符串(地址:长)

当任何不属于上述任一类别的函数被触发时,会触发编译错误
仅由 stapusr 组的成员使用。

只有 stapusr 组的成员不能使用其他内置的 tapset 函数。

ALTERNATE 运行时间


如上所述,systemtap 的默认运行时模式涉及构建和加载内核
模块,提出了各种安全权衡。 Systemtap 现在包含一个新的
原型后端,选择 --运行时=动态,它使用 Dyninst 来检测一个
运行时用户自己的进程。 这个后端不使用内核模块,也不
需要 root 权限,但在探测类型和其他方面受到限制
脚本可以使用的构造。

这个 动态 运行时在目标附加模式下运行,因此它确实需要一个 -c 指挥 or -x
电位诱导衰减 过程。 例如:

stap --runtime=dyninst -c 'stap -V' \
-e 'probe process.function("main")
{ println("来自 dyninst 的你好!") }'

可能需要禁用冲突的 selinux 检查

#setsebool allow_execstack 1

退出 状态


如果请求,systemtap 转换器通常返回成功代码 0
脚本已通过请求的传递成功处理和执行。 否则,
错误可能会打印到 stderr 并返回失败代码。 利用 -v or -副总裁 N
增加(全局或每次传递)详细程度以识别问题的根源。

在列表模式(-l-L),错误消息通常被抑制。 成功码 0
如果找到至少一个匹配的探针,则返回。

在第 5 轮中执行的脚本被 ^C / SIGINT 中断被认为是
成功。

弃用


随着时间的推移,脚本语言和 tapset 库的一些特性可能会发生
不兼容的更改,因此针对旧版本 systemtap 编写的脚本可能不兼容
运行时间更长。 在这些情况下,使用 systemtap 运行 systemtap 可能会有所帮助 - 兼容的 VERSION
标志,指定最后一个已知的工作版本。 使用 systemtap 运行
--检查版本 如果有任何可能的不兼容元素,flag 将输出警告
解析。 可以在新闻文件中找到弃用历史详细信息。

使用 onworks.net 服务在线使用 stap


免费服务器和工作站

下载 Windows 和 Linux 应用程序

Linux 命令

Ad




×
广告
❤️在这里购物、预订或购买——免费,有助于保持服务免费。