Solaris 动态跟踪指南

第 19 章 profile 提供器

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


注 –

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


profile-n 探测器

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

表 19–1 有效时间后缀

后缀 

时间单位 

nsec 或 ns

纳秒 

usec 或 us

微秒 

msec 或 ms

毫秒 

sec 或 s

秒 

min 或 m

分钟 

hour 或 h

小时 

day 或 d

天 

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 为非零值。因此,可以使用 arg0 和 arg1 来区分用户级和内核级,如以下简单示例所示:

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 章。

元素 

名称稳定性 

数据稳定性 

相关性类 

提供器 

发展中 

发展中 

公用

模块 

不稳定 

不稳定 

未知 

功能 

专用 

专用 

未知 

名称 

发展中 

发展中 

公用

参数 

发展中 

发展中 

公用