Solaris 动态跟踪指南

跟踪任意指令

您可以使用 pid 提供器跟踪用户函数中的任何指令。pid 提供器将根据需要,为函数中的每条指令创建探测器。每个探测器的名称即函数中与其对应的,以十六进制整数表示的指令的偏移量。例如,要启用与 bar.so 模块的 foo 函数中的偏移量为 0x1c 的指令(位于 PID 为 123 的进程中)关联的探测器,可使用以下命令:


# dtrace -n pid123:bar.so:foo:1c

要启用函数 foo 中的所有探测器(包括每条指令的探测器),可使用以下命令:


# dtrace -n pid123:bar.so:foo:

此命令展示了一种功能非常强大的、用于调试和分析用户应用程序的方法。由于很难重现不经常发生的错误,因此对其进行调试可能并不容易。通常,您可以在出现故障后确定问题,但这对于重构代码路径已太迟。以下示例演示了如何将 pid 提供器与推理跟踪(请参见第 13 章)进行结合,以便通过跟踪函数中的每条指令来解决该问题。


示例 33–2 errorpath.d:跟踪用户函数调用错误路径

pid$1::$2:entry
{
	self->spec = speculation();
	speculate(self->spec);
	printf("%x %x %x %x %x", arg0, arg1, arg2, arg3, arg4);
}

pid$1::$2:
/self->spec/
{
	speculate(self->spec);
}

pid$1::$2:return
/self->spec && arg1 == 0/
{
	discard(self->spec);
	self->spec = 0;
}

pid$1::$2:return
/self->spec && arg1 != 0/
{
	commit(self->spec);
	self->spec = 0;
}

执行 errorpath.d 将会生成与以下示例类似的输出:


# ./errorpath.d 100461 _chdir
dtrace: script './errorpath.d' matched 19 probes
CPU     ID                    FUNCTION:NAME
  0  25253                     _chdir:entry 81e08 6d140 ffbfcb20 656c73 0
  0  25253                     _chdir:entry
  0  25269                         _chdir:0
  0  25270                         _chdir:4
  0  25271                         _chdir:8
  0  25272                         _chdir:c
  0  25273                        _chdir:10
  0  25274                        _chdir:14
  0  25275                        _chdir:18
  0  25276                        _chdir:1c
  0  25277                        _chdir:20
  0  25278                        _chdir:24
  0  25279                        _chdir:28
  0  25280                        _chdir:2c
  0  25268                    _chdir:return