2.5 Dtrace
目录
今天我们来讲解第一个动态追踪技术 DTrace, 它是动态追踪技术的鼻祖
1. Dtrace 简介
Solaris 系统的 DTrace 是动态追踪技术的鼻祖,它提供了一个通用的观测框架,并可以使用 D 语言进行自由扩展。
DTrace 的工作原理如下图所示。它的运行常驻在内核中,用户可以通过 dtrace 命令,把 D 语言编写的追踪脚本,提交到内核中的运行时来执行。
DTrace 本身依然无法在 Linux 中运行。很多工程师都尝试过把 DTrace 移植到 Linux 中,这其中,最著名的就是 RedHat 主推的 SystemTap。
2. DTrace 语法
2.1 探针
provider:module:function:name
:
- provider: 相关探针的集合
- module,function: 探针指示的代码位置的代号
- name: 探针的名字
- 可以使用通配符,"::" == “:*:”
provider
DTrace 包含的 provider 如下所示:
provider | 作用 |
---|---|
syscal | 系统调用 |
vminfo | 虚拟内存统计 |
sysinfo | 系统统计 |
profile | 任意频率的采样 |
sched | 内核调度事件 |
proc | 进程级别事件 |
io | 块设备接口跟踪,即磁盘I/O |
pid | 用户级别动态跟踪 |
tcp | TCP协议事件,连接、发送和接收 |
ip | IP 协议事件,发送和接收 |
fbt | 内核级别动态追踪 |
高级语言的 provider |
参数
探针通过一组称为参数的变量来提供数据。例如系统调用 syscal 给每一个系统调用都做了入口(entry)和返回(return)探针。这组参数变量如下:
- 入口: arg0….argN,表示系统调用的参数
- 返回: arg0 或 arg1,表示返回值,errno 也会设置
2.2 D 语言
D 语言定义了DTrace 的语法。DTrace 语句如下:
probe_description /predicate/ {action}
:
- probe_description: 探针
- predicate: 可选的过滤表达式
- action: 探针触发时执行的操作,分号分隔的语句
|
|
内置变量
内置变量用来计算和判断
变量 | 描述 |
---|---|
execname | 执行在CPU上的进程名 |
uid | 执行在CPU上的用户ID |
pid | 执行在CPU上的进程PID |
timestamp | 自启动以来的纳秒数 |
vtimestamp | CPU上的线程时间,单位是纳秒 |
arg0..N | 探针参数(uint64_t) |
args[0]…[N] | 探针参数(类型化的) |
curthread | 指向当前线程内核结构的指针 |
probefunc | 探针描述的函数组件 |
probename | 当前探针名称 |
curpsinfo | 当前进程信息 |
变量类型
类型 | 前缀 | 作用域 | 开销 | 多CPU安全 | 赋值示例 |
---|---|---|---|---|---|
聚合变量 | @ | 全局 | 低 | 是 | @x = count(); |
带键聚合变量 | @[] | 全局 | 低 | 是 | @x[pid] = count(); |
从句局部变量 | this-> | 从句实例 | 非常低 | 是 | this->x = 1; |
线程局部变量 | self-> | 线程内 | 中等 | 是 | self->x = 1; |
标量 | 无 | 全局 | 中下 | 否 | x = 1; |
关联数组 | 无 | 全局 | 中上 | 否 | x[y] = 1 |
说明:
- 线程局部变量: 作用域线程内,像时间戳这样的数据容易与线程关联
- 从句局部变量: 用于中间计算,只在针对同一探针描述的 action 子句有效
- 聚合变量: 可以由 CPU 单独计算汇总后在传递到用户空间
action
action | 作用 |
---|---|
trace(arg) | 打印arg |
printf(format, arg…) | 格式化输出 |
stringof(addr) | 返回来自内核空间的字符串 |
copyinstr(addr) | 返回用户空间地址的字符串 内核会执行一次从用户空间到内核空间的复制 |
stack(count) | 打印内核级别栈追踪,如果有 count 按 count 截断 |
ustack(count) | 打印用户级别栈追踪,如果有 count 按 count 截断 |
func(pc) | 从内核程序计数器,返回内核函数名 |
ufunc(pc) | 从用户程序计数器,返回用户函数名 |
exit(status) | 退出DTrace并返回状态 |
聚合变量的特有的 action
action | 作用 |
---|---|
trunc(@agg, count) | 截断聚合变量 删除全部键,或者按照 count 指定的键数目截断 |
clear(@agg) | 删除聚合变量的值,键保留 |
printa(format, @agg) | 格式化打印聚合变量 |
count() | 发生计数 |
sum(value) | value 求和 |
min(value) | |
max(value) | |
quantize(value) | 用 2 的幂次方直方图统计 value |
lquantize(value,min,max,step) | 用给定最下值,最大值和步进值做线性直方图记录 value |
|
|
2.3 DTrace 脚本
|
|