1 Star2 Stars3 Stars4 Stars5 Stars (还没有评分)
Loading...

DTrace profile provider详解

DTrace中,profile provider是一种特殊的provider,这个provider提供的probe起到一种类似定时器的作用。它可以根据用户设置的频率周期性地触发,这样用户就可以定期地采集感兴趣的数据,汇总以后作分析。

Profile provider提供两种probeprofile-ntick-n。其中n代表每秒probe触发的频率,n后面也可以带上时间后缀。举个例子:profile-100nsns表示纳秒),表示每100纳秒触发一次。两种probe的区别在于:每个CPU都会触发执行profile-n probe,而只有一个CPU会触发执行tick-n probe,所以使用profile-n probe时,需要考虑使用cpu-safe的变量。让我们来做个试验,在Solaris机器上,分别执行下面命令:“dtrace -n 'profile-1 {}‘”和“dtrace -n 'tick-1 {}‘”,输出如下:

bash-3.2# dtrace -n 'profile-1 {}'
dtrace: description 'profile-1 ' matched 1 probe
CPU     ID                    FUNCTION:NAME
  0  58553                       :profile-1 
  1  58553                       :profile-1 
  2  58553                       :profile-1 
  3  58553                       :profile-1 
  4  58553                       :profile-1 
  5  58553                       :profile-1 
  6  58553                       :profile-1 
  7  58553                       :profile-1 
  8  58553                       :profile-1 
  9  58553                       :profile-1 
 10  58553                       :profile-1 
 11  58553                       :profile-1 
 12  58553                       :profile-1 
 13  58553                       :profile-1 
 14  58553                       :profile-1 
 15  58553                       :profile-1 

bash-3.2# dtrace -n 'tick-1 {}'
dtrace: description 'tick-1 ' matched 1 probe
CPU     ID                    FUNCTION:NAME
  9  53931                          :tick-1 
  9  53931                          :tick-1 
  9  53931                          :tick-1 
  9  53931                          :tick-1 

从输出结果可以看到,profile-1 probe在所有CPU都执行了,而tick-1 probe只在一个CPU上执行了。

Profile probe有两个输入参数:arg0arg1arg0的值是probe触发时,进程内核空间的指令计数器(program counter)的值,如果当前进程运行在用户空间,则这个值是0。与arg0相反,arg1的值是probe触发时,进程用户空间的指令计数器(program counter)的值,如果当前进程运行在内核空间,则这个值是0。简单地讲,arg00,则arg1一定不为0,反之亦然。所以可以用输入参数来得知进程当前的运行状态,就像下面这个简单的例子:

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

最后以Brendan Greggcpuwalk.d脚本为例,来具体看一下如何使用profile probe

#pragma D option quiet
#pragma D option defaultargs

inline int MAXCPUID = 1024;

dtrace:::BEGIN
{
        $1 ? printf("Sampling...\n") :
            printf("Sampling... Hit Ctrl-C to end.\n");
        seconds = 0;
}

profile:::profile-1000hz
/pid/
{
        @sample[pid, execname] = lquantize(cpu, 0, MAXCPUID, 1);
}

profile:::tick-1sec
{
        seconds++;
}

profile:::tick-1sec
/seconds == $1/
{
        exit(0);
}

dtrace:::END
{
        printa("\n     PID: %-8d CMD: %s\n%@d", @sample);
}

这个脚本用来检查是否进程是否在多个CPU上执行,运行脚本输出:

bash-3.2# ./cpuwalk.d 
Sampling... Hit Ctrl-C to end.
^C

     PID: 12476    CMD: mysqld

           value  ------------- Distribution ------------- count    
               0 |                                         0        
               1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 4        
               2 |                                         0        

     PID: 24912    CMD: tail

           value  ------------- Distribution ------------- count    
               3 |                                         0        
               4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1        
               5 |                                         0        

     PID: 19982    CMD: java

           value  ------------- Distribution ------------- count    
               4 |                                         0        
               5 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1        
               6 |                                         0        

     PID: 805      CMD: lsi_mrdsnmpagent

           value  ------------- Distribution ------------- count    
               1 |                                         0        
               2 |@@@@@@@@@@@@@@@@@@@@                     1        
               3 |                                         0        
               4 |                                         0        
               5 |                                         0        
               6 |                                         0        
               7 |                                         0        
               8 |                                         0        
               9 |@@@@@@@@@@@@@@@@@@@@                     1        
              10 |                                         0        

     PID: 3        CMD: fsflush

           value  ------------- Distribution ------------- count    
               0 |                                         0        
               1 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 12       
               2 |                                         0        

     PID: 6870     CMD: python

           value  ------------- Distribution ------------- count    
              11 |                                         0        
              12 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1        
              13 |                                         0        

     PID: 647      CMD: java

           value  ------------- Distribution ------------- count    
              13 |                                         0        
              14 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1        
              15 |                                         0        

     PID: 1683     CMD: python

           value  ------------- Distribution ------------- count    
               9 |                                         0        
              10 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 2        
              11 |                                         0        

     PID: 10156    CMD: java

           value  ------------- Distribution ------------- count    
               3 |                                         0        
               4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@         4        
               5 |@@@@@@@@                                 1        
               6 |                                         0        

     PID: 11123    CMD: python

           value  ------------- Distribution ------------- count    
              10 |                                         0        
              11 |@@@@@@@@@@@@@@@@@@@@                     1        
              12 |                                         0        
              13 |                                         0        
              14 |                                         0        
              15 |@@@@@@@@@@@@@@@@@@@@                     1        
              16 |                                         0        

     PID: 24913    CMD: dtrace

           value  ------------- Distribution ------------- count    
               9 |                                         0        
              10 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 3        
              11 |                                         0        

     PID: 23874    CMD: java

           value  ------------- Distribution ------------- count    
               3 |                                         0        
               4 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 8        
               5 |                                         0  

从执行结果可以看出,8051015611123进程都在多个CPU上执行。

参考资料:
(1)profile Provider
(2)DTraceToolkit

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.