Macos `Mac OS X上的probemod`打印神秘的hexdump而不是模块名
以下内容可以很好地获取某个命令进行的每个系统调用的函数名(这里我们跟踪Macos `Mac OS X上的probemod`打印神秘的hexdump而不是模块名,macos,dtrace,Macos,Dtrace,以下内容可以很好地获取某个命令进行的每个系统调用的函数名(这里我们跟踪date命令): sudodtrace-n'syscall:::条目{@[probefunc]=count();}'-c“日期” 它产生如下输出: read_nocancel 13 bsdthread_ctl 15 ioctl 26 现在知道模块名也很好。因此,我将probemod添加到我的跟踪中,如下所示: sudodtrace-n'syscall:::条目{@[probemod,probefunc
date
命令):
sudodtrace-n'syscall:::条目{@[probefunc]=count();}'-c“日期”
它产生如下输出:
read_nocancel 13
bsdthread_ctl 15
ioctl 26
现在知道模块名也很好。因此,我将probemod
添加到我的跟踪中,如下所示:
sudodtrace-n'syscall:::条目{@[probemod,probefunc]=count();}'-c“date”
它产生了这样一个(诚然很时髦,但最终毫无用处)的结果:
基于:我希望输出显示当前探测器的模块名。事实上,有证据表明probemod
可以解析为库名称,如libumem.so.1
或libc.so.1
。在我的电脑上不是这样
我使用的是Mac OS X Sierra 10.12.3测试版
这是DTrace的预期行为,还是MacOSX的实现有缺陷?还是我做错了什么?尝试在函数中使用stack()
和/或ustack()
:
示例输出:
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
堆栈()函数函数
void stack(int nframes)
void stack(void)
void ustack(int nframes, int strsize)
void ustack(int nframes)
void ustack(void)
stack()
操作会记录指向目标的内核堆栈跟踪
缓冲器内核堆栈的深度由
n帧。如果没有为nframes提供值,堆栈操作将记录
stackframes选项指定的堆栈帧数。
ustack()
函数
void stack(int nframes)
void stack(void)
void ustack(int nframes, int strsize)
void ustack(int nframes)
void ustack(void)
ustack()
操作记录指向目标的用户堆栈跟踪
缓冲器用户堆栈的深度等于中指定的值
n帧。如果nframes没有值,ustack操作将记录
ustackframes选项指定的堆栈帧数。
ustack()
操作确定调用帧的地址
当探测器开火时。ustack()
操作不会转换
将帧堆叠到符号中,直到DTrace使用者处理
ustack()
用户级别的操作。如果strsize的值为
指定而不是零,则ustack()
操作分配指定的
字符串空间量,并使用它来执行地址到符号
直接从内核进行翻译
↳ 尝试在函数中使用stack()
和/或ustack()
:
示例输出:
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
堆栈()函数函数
void stack(int nframes)
void stack(void)
void ustack(int nframes, int strsize)
void ustack(int nframes)
void ustack(void)
stack()
操作会记录指向目标的内核堆栈跟踪
缓冲器内核堆栈的深度由
n帧。如果没有为nframes提供值,堆栈操作将记录
stackframes选项指定的堆栈帧数。
ustack()
函数
void stack(int nframes)
void stack(void)
void ustack(int nframes, int strsize)
void ustack(int nframes)
void ustack(void)
ustack()
操作记录指向目标的用户堆栈跟踪
缓冲器用户堆栈的深度等于中指定的值
n帧。如果nframes没有值,ustack操作将记录
ustackframes选项指定的堆栈帧数。
ustack()
操作确定调用帧的地址
当探测器开火时。ustack()
操作不会转换
将帧堆叠到符号中,直到DTrace使用者处理
ustack()
用户级别的操作。如果strsize的值为
指定而不是零,则ustack()
操作分配指定的
字符串空间量,并使用它来执行地址到符号
直接从内核进行翻译
↳ 系统调用提供程序不提供探测模块。如果它这样做了,则不是启动(调用)系统调用的模块,而是系统调用本身的模块。这就是为什么它没有意义,如果它有意义的话,它就不是你想要的 为确认,列出探头并观察空的“模块”列:
您看到的十六进制转储基本上是一个充满256个空字节的缓冲区,这就是缺少的探测模块的明显表示方式。系统调用提供程序不提供探测模块。如果它这样做了,则不是启动(调用)系统调用的模块,而是系统调用本身的模块。这就是为什么它没有意义,如果它有意义的话,它就不是你想要的 为确认,列出探头并观察空的“模块”列:
您看到的十六进制转储基本上是一个充满256个空字节的缓冲区,这就是缺少的探测模块的明显表示方式。在这台计算机上:
@[probefunc,stack(1),ustack(1)]=count()
分别给出:“ioctl”、“kernelunix\u syscall64+0x24a”和“libsystem\u kernel.dylib
\uu ioctl+0xa”,并使用一些错误的换行符使事情复杂化。这当然证明了DTrace可以看到探测器的模块名,但除非有办法从这些字符串中选择重要部分:否则这不能完全替代probemod
。我仍然很好奇为什么probemod
的行为与预期的不同。我认为您需要使用格式字符串(printf()
)或类似的字符串才能获得所需的输出。probmod
在哪里表现不同?从您链接的示例来看,它看起来几乎相同,除非我遗漏了什么。在我链接的示例中,作者使用@[probemod,probefunc,arg0]=count()
和printa(“probemod=%s,probefunc=%s size=%d,count=%@d\n”,@)代码>,并获取以下结果:probemod=libumem.so.1 probefunc=malloc size=2048 count=6
。换句话说:probemod=libumem.so.1
(这是一个比由ustack(1)
返回的字符串短得多的字符串)…它输出:一些空格、一个由波浪号分隔的元组、一个