以下工作可以很好地获取某些命令所产生的每个系统调用的函数名称(这里我们跟踪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.1
或libc.so.1
等库名称。我的电脑不是这样。
我正在使用Mac OS X Sierra 10.12.3 Beta。
这是DTrace的预期行为,还是Mac OS X的实现有错误?或者我做错了什么?
答案 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个空字节的缓冲区,这就是缺少探测模块的表现方式。