Mac OS X 上的 `probemod` 打印神秘的 hexdump 而不是模块名称
`probemod` on Mac OS X prints mysterious hexdump instead of module name
下面的代码可以很好地获取某个命令发出的每个系统调用的函数名(这里我们跟踪 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"
它产生了这个(诚然很时髦,但最终没有帮助)十六进制转储:
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: I expected the output to show the module name of the current probe. Indeed, there exists a tutorial,表明 probemod
可以解析为库名称,例如 libumem.so.1
或 libc.so.1
。在我的电脑上不是这样。
我正在使用 Mac OS X Sierra 10.12.3 Beta。
这是 DTrace 的预期行为,还是 Mac OS X 的实现有错误?还是我做错了什么?
尝试在您的函数中使用 stack()
and/or 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)
The stack()
action records a kernel stack trace to the directed
buffer. The depth of the kernel stack is given by the value given in
nframes. If no value is given for nframes, the stack action records a
number of stack frames specified by the stackframes option. The
ustack()
函数
void ustack(int nframes, int strsize)
void ustack(int nframes)
void ustack(void)
The ustack()
action records a user stack trace to the directed
buffer. The depth of the user stack is equal to the value specified in
nframes. If there is no value for nframes, the ustack action records a
number of stack frames that is specified by the ustackframes option.
The ustack()
action determines the address of the calling frames
when the probe fires. The ustack()
action does not translate the
stack frames into symbols until the DTrace consumer processes the
ustack()
action at the user level. If a value for strsize is
specified and not zero, the ustack()
action allocates the specified
amount of string space and uses it to perform address-to-symbol
translation directly from the kernel.
↳https://docs.oracle.com/cd/E18752_01/html/819-5488/gcfbn.html#gcgfo
系统调用提供程序不提供探测模块。如果是这样,那将不是启动(调用)系统调用的模块,而是系统调用本身的模块。这就是为什么它没有意义,如果有的话,也不是你想要的。
为了确认,列出探测器并观察空的 "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 个空字节的缓冲区,这就是缺失的探测模块的明显表现形式。
下面的代码可以很好地获取某个命令发出的每个系统调用的函数名(这里我们跟踪 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"
它产生了这个(诚然很时髦,但最终没有帮助)十六进制转储:
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: I expected the output to show the module name of the current probe. Indeed, there exists a tutorial,表明 probemod
可以解析为库名称,例如 libumem.so.1
或 libc.so.1
。在我的电脑上不是这样。
我正在使用 Mac OS X Sierra 10.12.3 Beta。
这是 DTrace 的预期行为,还是 Mac OS X 的实现有错误?还是我做错了什么?
尝试在您的函数中使用 stack()
and/or 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)
The
stack()
action records a kernel stack trace to the directed buffer. The depth of the kernel stack is given by the value given in nframes. If no value is given for nframes, the stack action records a number of stack frames specified by the stackframes option. The
ustack()
函数
void ustack(int nframes, int strsize)
void ustack(int nframes)
void ustack(void)
The
ustack()
action records a user stack trace to the directed buffer. The depth of the user stack is equal to the value specified in nframes. If there is no value for nframes, the ustack action records a number of stack frames that is specified by the ustackframes option. Theustack()
action determines the address of the calling frames when the probe fires. Theustack()
action does not translate the stack frames into symbols until the DTrace consumer processes theustack()
action at the user level. If a value for strsize is specified and not zero, theustack()
action allocates the specified amount of string space and uses it to perform address-to-symbol translation directly from the kernel.
↳https://docs.oracle.com/cd/E18752_01/html/819-5488/gcfbn.html#gcgfo
系统调用提供程序不提供探测模块。如果是这样,那将不是启动(调用)系统调用的模块,而是系统调用本身的模块。这就是为什么它没有意义,如果有的话,也不是你想要的。
为了确认,列出探测器并观察空的 "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 个空字节的缓冲区,这就是缺失的探测模块的明显表现形式。