Solaris 动态跟踪指南

第 19 章 profile 提供器

profile 提供器提供了与按所指定固定时间间隔触发、基于时间的中断关联的探测器。这些不固定探测器不与任何特定执行点关联,而是与异步中断事件关联。这些探测器可用于按单位时间对系统状态的某些方面进行采样,然后使用这些样本来推断系统行为。如果采样速率较高或采样时间较长,则推断可能更准确。使用 DTrace 操作时,可以使用 profile 提供器对系统中的任何内容进行实际采样。例如,您可对当前线程的状态、CPU 的状态或当前的计算机指令进行采样。


注 –

来自 profile 提供器的探测器无法访问线程局部变量。使用特殊标识符 self 来引用具有此类探测器的线程局部变量将不产生任何输出。


profile-n 探测器

profile-n 探测器在每个 CPU 中以高中断级别按固定的时间间隔触发。探测器的触发时间间隔以 n 值表示:中断源将每秒触发 n 次。n 也可带可选的时间前缀,在此情况下,n 将解释为由后缀表示的单位。表 19–1 中列出了有效的后缀和这些后缀表示的单位。

表 19–1 有效时间后缀

后缀 

时间单位 

nsecns

纳秒 

usecus

微秒 

msecms

毫秒 

secs

秒 

minm

分钟 

hourh

小时 

dayd

天 

hz

赫兹(每秒频率) 

以下示例创建一个按 97 赫兹触发,以便对当前正在运行的进程进行采样的探测器:

#pragma D option quiet

profile-97
/pid != 0/
{
	@proc[pid, execname] = count();
}

END
{
	printf("%-8s %-40s %s\n", "PID", "CMD", "COUNT");
	printa("%-8d %-40s %@d\n", @proc);
}

运行上例一小段时间将产生与以下示例类似的输出:


# dtrace -s ./prof.d
^C
PID      CMD                                      COUNT
223887   sh                                       1
100360   httpd                                    1
100409   mibiisa                                  1
223887   uname                                    1
218848   sh                                       2
218984   adeptedit                                2
100224   nscd                                     3
3        fsflush                                  4
2        pageout                                  6
100372   java                                     7
115279   xterm                                    7
100460   Xsun                                     7
100475   perfbar                                  9
223888   prstat                                   15

也可使用 profile-n 提供器对有关正在运行进程的信息进行采样。以下示例 D 脚本使用一个 1,001 赫兹的 profile 探测器对所指定进程的当前优先级进行采样:

profile-1001
/pid == $1/
{
	@proc[execname] = lquantize(curlwpsinfo->pr_pri, 0, 100, 10);
}

要查看运行中的此示例脚本,请在一个窗口中键入下列命令:


$ echo $$
12345
$ while true ; do let i=0 ; done

在另一个窗口中运行 D 脚本一小段时间,用 echo 命令返回的 PID 替换 12345


# dtrace -s ./profpri.d 12345
 dtrace: script './profpri.d' matched 1 probe
^C
ksh                                               
           value  ------------- Distribution ------------- count    
             < 0 |                                         0        
               0 |@@@@@@@@@@@@@@@@@@@@@                    7443     
              10 |@@@@@@                                   2235     
              20 |@@@@                                     1679     
              30 |@@@                                      1119     
              40 |@                                        560      
              50 |@                                        554      
              60 |                                         0 

此输出显示了分时调度类的偏差。由于 shell 进程在 CPU 上旋转,因此其优先级经常会被系统降低。如果该 shell 进程运行不频繁,则其优先级将更高。要查看此结果,请在此旋转的 shell 中键入 Ctrl-C 组合键,然后再次运行脚本:


# dtrace -s ./profpri.d 494621
 dtrace: script './profpri.d' matched 1 probe

现在于 shell 中键入一些字符。终止 DTrace 脚本时,将会显示与以下示例类似的输出:


ksh                                               
           value  ------------- Distribution ------------- count    
              40 |                                         0        
              50 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 14       
              60 |                                         0

由于等待用户输入时 shell 进程进入休眠状态而不是在 CPU 中旋转,所以当真正运行时,它将以较高的优先级运行。

tick-n 探测器

profile-n 探测器一样,tick-n 探测器以高中断级别按固定时间间隔触发。但是,与在每个 CPU 中都触发的 profile-n 探测器不同,tick-n 探测器仅按时间间隔在一个 CPU 中触发。实际的 CPU 可能随时间变化。与 profile-n 探测器一样,n 缺省为每秒的速率,但是也可以带有可选的时间后缀。tick-n 探测器具有多种用途(例如提供某些定期输出或执行定期操作)。

参数

profile 探测器的参数如下所示:

arg0

触发探测器时内核中的程序计数器 (program counter, PC),如果在触发探测器时内核中未执行当前进程,则为 0 

arg1

触发探测器时用户级进程中的程序计数器,如果在触发探测器时内核中正在执行当前进程,则为 0 

从说明可以判断出,如果 arg0 为非零值,则 arg1 为零;如果 arg0 为零,则 arg1 为非零值。因此,可以使用 arg0arg1 来区分用户级和内核级,如以下简单示例所示:

profile-1ms
{
	@ticks[arg0 ? "kernel" : "user"] = count();
}

计时器分辨率

profile 提供器使用操作系统中的任意分辨率间隔计时器。在不支持真正基于任意分辨率时间中断的体系结构中,此频率受系统时钟频率的限制,由 hz 内核变量指定。此类体系结构中频率高于 hz 的探测器将每隔 1/hz 秒触发若干次。例如,这种体系结构中一个 1000 赫兹的 profile 探测器(hz 设置为 100)将每隔 10 毫秒快速连续触发 10 次。在支持任意分辨率的平台上,1000 赫兹的 profile 探测器将准确地每隔 1 毫秒触发一次。

以下示例测试给定体系结构的分辨率:

profile-5000
{
	/*
	 * We divide by 1,000,000 to convert nanoseconds to milliseconds, and
	 * then we take the value mod 10 to get the current millisecond within
	 * a 10 millisecond window.  On platforms that do not support truly
	 * arbitrary resolution profile probes, all of the profile-5000 probes
	 * will fire on roughly the same millisecond.  On platforms that
	 * support a truly arbitrary resolution, the probe firings will be
	 * evenly distributed across the milliseconds.
	 */
	@ms = lquantize((timestamp / 1000000) % 10, 0, 10, 1);
}

tick-1sec
/i++ >= 10/
{
	exit(0);
}

在支持任意分辨率 profile 探测器的体系结构中,运行此示例脚本将产生均匀分布:


# dtrace -s ./restest.d
 dtrace: script './restest.d' matched 2 probes
CPU     ID                    FUNCTION:NAME
  0  33631                       :tick-1sec 


           value  ------------- Distribution ------------- count    
             < 0 |                                         0        
               0 |@@@                                      10760    
               1 |@@@@                                     10842    
               2 |@@@@                                     10861    
               3 |@@@                                      10820    
               4 |@@@                                      10819    
               5 |@@@                                      10817    
               6 |@@@@                                     10826    
               7 |@@@@                                     10847    
               8 |@@@@                                     10830    
               9 |@@@@                                     10830

在不支持任意分辨率 profile 探测器的体系结构中,运行此示例脚本将产生不均匀分布:


# dtrace -s ./restest.d
 dtrace: script './restest.d' matched 2 probes
 CPU     ID                    FUNCTION:NAME
  0  28321                       :tick-1sec 


           value  ------------- Distribution ------------- count    
               4 |                                         0        
               5 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@  107864   
               6 |                                         424      
               7 |                                         255      
               8 |                                         496      
               9 |                                         0

在这些体系结构中,可在 /etc/system 中手动调整 hz,以提高有效的配置文件分辨率。

当前,UltraSPARC (sun4u) 的所有变体均支持任意分辨率 profile 探测器。x86 体系结构 (i86pc) 的许多变体也支持任意分辨率 profile 探测器,但是一些较旧的变体不支持。

探测器创建

与其他提供器不同,profile 提供器根据需要动态创建探测器。因此,所需的 profile 探测器可能并未在所有探测器列表中显示(例如,通过使用 dtrace -l -P profile),但在显式启用该探测器时将会创建它。

在支持任意分辨率 profile 探测器的体系结构中,时间间隔太短将导致计算机连续产生基于时间的中断,从而拒绝计算机上的服务。为了防止出现这种情况,profile 提供器将自动拒绝创建会导致时间间隔小于两百微秒的任何探测器。

稳定性

profile 提供器使用 DTrace 的稳定性机制描述其稳定性,如下表所示。有关稳定性机制的更多信息,请参见第 39 章

元素 

名称稳定性 

数据稳定性 

相关性类 

提供器 

发展中 

发展中 

公用

模块 

不稳定 

不稳定 

未知 

功能 

专用 

专用 

未知 

名称 

发展中 

发展中 

公用

参数 

发展中 

发展中 

公用