如何修复已启用探测器的错误:无效地址(0x0)?

时间:2016-04-08 17:29:26

标签: dtrace probe

我发现了以下错误:

  

dtrace: error on enabled probe ID 3 (ID 7343: php15810:php:dtrace_execute_ex:function-return): invalid address (0x0) in action #2 at DIF offset 24

当我试图跟踪我的PHP脚本(sudo ./trace-php.d)时。

基本上我想要实现的是通过PHP函数显示分发时间/计数。它似乎有效,但我对此错误感到恼火。我知道我可以将其发送给/dev/null,但我想了解并修复它。

这是我的dtrace代码:

#!/usr/sbin/dtrace -Zs
#pragma D option quiet
php*:::function-entry
{
    self->vts = timestamp;
    self->cmd = arg0
}

php*:::function-return
/self->vts/
{
    @time[copyinstr(self->cmd)] = quantize(timestamp - self->vts);
    @num = count();
    self->vts = 0;
    self->cmd = 0;
}

profile:::tick-2s
{
  printf("\nPHP commands/second total: ");
  printa("%@d; commands latency (ns) by pid & cmd:", @num);
  printa(@time);
  clear(@time);
  clear(@num);
}

示例输出(运行一些php脚本时)是:

dtrace: error on enabled probe ID 3 (ID 7343: php15810:php:dtrace_execute_ex:function-return): invalid address (0x0) in action #2 at DIF offset 24
dtrace: error on enabled probe ID 3 (ID 7343: php15810:php:dtrace_execute_ex:function-return): invalid address (0x0) in action #2 at DIF offset 24
dtrace: error on enabled probe ID 3 (ID 7343: php15810:php:dtrace_execute_ex:function-return): invalid address (0x0) in action #2 at DIF offset 24
dtrace: error on enabled probe ID 3 (ID 7343: php15810:php:dtrace_execute_ex:function-return): invalid address (0x0) in action #2 at DIF offset 24

PHP commands/second total: 1549; commands latency (ns) by pid & cmd:
  variable_get                                      
           value  ------------- Distribution ------------- count    
            1024 |                                         0        
            2048 |@@@@@@@@@@@@@@@@@@@@@@@@@@@              4        
            4096 |@@@@@@@                                  1        
            8192 |@@@@@@@                                  1        
           16384 |                                         0        

  __construct                                       
           value  ------------- Distribution ------------- count    
            1024 |                                         0        
            2048 |@@@@@@@@@@@@@@@@@@@@                     3        
            4096 |@@@@@@@@@@@@@                            2        
            8192 |@@@@@@@                                  1        
           16384 |                                         0        

  features_array_diff_assoc_recursive               
           value  ------------- Distribution ------------- count    
           16384 |                                         0        
           32768 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ 1        
           65536 |                                         0        

  features_export_info                              
           value  ------------- Distribution ------------- count    
            2048 |                                         0        
            4096 |@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@        122      
            8192 |@@@@@@                                   23       
           16384 |@                                        4        
           32768 |                                         0    

1 个答案:

答案 0 :(得分:1)

这可能会做你想要的,通过将 php * ::: function-return 探针拆分成不同的子句 - 一个用于是否要打印输出(基于是否无论你在第一个探测子句中做了什么或没做过什么,都要清除你的线程局部变量。

这利用了DTrace按照您定义子句的确切顺序为每个探测执行代码的事实。

此示例还为您的自变量使用 probefunc 和线程ID( tid )的唯一键组合,因此您不会意外覆盖这些线程下降到函数调用时的局部变量:

#!/usr/sbin/dtrace -Zs

#pragma D option quiet

php*:::function-entry
{
    self->vts[tid,probefunc] = timestamp;
    self->cmd[tid,probefunc] = arg0
}

php*:::function-return
/self->vts[tid,probefunc] && self->cmd[tid,probefunc]/
{
    @time[copyinstr(self->cmd[tid,probefunc])] =
      quantize(timestamp - self->vts[tid,probefunc]);
    @num = count();
}

php*:::function-return
/self->vts[tid,probefunc]/
{
    self->vts[tid,probefunc] = 0;
    self->cmd[tid,probefunc] = 0;
}

profile:::tick-2s
{
  printf("\nPHP commands/second total: ");
  printa("%@d; commands latency (ns) by pid & cmd:", @num);
  printa(@time);
  clear(@time);
  clear(@num);
}

如果任何PHP函数都是Tail Call Optimized,则上述操作可能无法正常工作。要查看您是否符合此条件,请运行以下命令:

#!/usr/sbin/dtrace -s

#pragma D option quiet

php*:::function-entry
{
  @e[probefunc,probename] = count();
}

php*:::function-return
{
  @r[probefunc,probename] = count();
}

tick-10sec
{
  printf("ENTRY POINTS\n");
  printa(@e);

  printf("RETURN POINTS\n");
  printa(@r);

  exit(0);
}

对入口点和返回点进行排序 - 计数不必完全匹配,但您希望每个探测函数和名称组合在入口点和返回点之间匹配。特别警惕任何没有列出返回点的人。这些很可能是Tail Call Optimized,你想要从你的分析中排除那些,因为你永远无法计时。