Mac OS X上的`probemod`打印神秘的hexdump而不是模块名

时间:2017-01-23 20:47:57

标签: macos dtrace

以下工作可以很好地获取某些命令所产生的每个系统调用的函数名称(这里我们跟踪date命令):

sudo dtrace -n 'syscall:::entry { @[probefunc] = count(); }' -c "date"

产生如下输出:

read_nocancel  13
bsdthread_ctl  15
ioctl          26

现在知道模块名称真的很好。所以我将probemod添加到我的跟踪中,如下所示:

sudo dtrace -n 'syscall:::entry { @[probemod, probefunc] = count(); }' -c "date"

它产生了这个(无可置疑的,但最终没有帮助)hexdump:

           0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f  0123456789abcdef
       0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      40: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      50: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      60: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      70: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      90: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      a0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
      f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00  ................
ioctl                                                            30

基于Oracle's documentation:我希望输出显示当前探测的模块名称。实际上,存在a tutorial表明probemod可以解析为libumem.so.1libc.so.1等库名称。我的电脑不是这样。

我正在使用Mac OS X Sierra 10.12.3 Beta。

这是DTrace的预期行为,还是Mac OS X的实现有错误?或者我做错了什么?

2 个答案:

答案 0 :(得分:1)

尝试在您的函数中使用stack()和/或ustack()

sudo dtrace -n 'syscall:::entry { @[probefunc, stack(), ustack()] = count(); }' -c "date"

示例输出:

ioctl                                             
            kernel`unix_syscall64+0x24a
            kernel`hndl_unix_scall64+0x16

            libsystem_kernel.dylib`__ioctl+0xa
            libdtrace.dylib`dtrace_sleep+0x87
            dtrace`main+0x1d15
            libdyld.dylib`start+0x1
            dtrace`0x5
              1

stack()功能

void stack(int nframes)
void stack(void)
  

stack()操作将内核堆栈跟踪记录到定向   缓冲。内核堆栈的深度由给定的值给出   将为nframes。如果没有为nframes赋值,则堆栈操作记录a   stackframes选项指定的堆栈帧数。在

ustack()功能

void ustack(int nframes, int strsize)
void ustack(int nframes)
void ustack(void)
  

ustack()操作将用户堆栈跟踪记录到定向   缓冲。用户堆栈的深度等于中指定的值   将为nframes。如果nframe没有值,则ustack操作会记录a   ustackframes选项指定的堆栈帧数。   ustack()操作确定调用帧的地址   当探测器发射时ustack()操作无法翻译   将帧堆叠成符号,直到DTrace使用者处理   用户级别的ustack()操作。如果strsize的值是   指定且不为零,ustack()操作分配指定的   字符串空间量并使用它来执行地址到符号   直接从内核翻译。

https://docs.oracle.com/cd/E18752_01/html/819-5488/gcfbn.html#gcgfo

答案 1 :(得分:1)

系统调用提供程序不提供探测模块。如果确实如此,它将不是启动(调用)系统调用的模块,它将是系统调用本身的模块。这就是为什么它没有意义,如果确实如此,那就不是你想要的。

要确认,请列出探针并观察空的" MODULE"柱:

$ sudo dtrace -l -n 'syscall:::entry'
   ID   PROVIDER            MODULE                          FUNCTION NAME
  156    syscall                                             syscall entry
  158    syscall                                                exit entry
  160    syscall                                                fork entry
  162    syscall                                                read entry
  164    syscall                                               write entry
  .
  .
  .

你看到的十六进制转储基本上是一个满256个空字节的缓冲区,这就是缺少探测模块的表现方式。