dtrace
dtrace -n 'syscall::read:entry { @[fds[arg0].fi_fs] = count(); }'
我想找到参数read fds
trace -lvn 'syscall::*read*:entry'
933 syscall read_nocancel entry
Probe Description Attributes
Identifier Names: Private
Data Semantics: Private
Dependency Class: ISA
Argument Attributes
Identifier Names: Private
Data Semantics: Private
Dependency Class: ISA
Argument Types
None
963 syscall readv_nocancel entry
Probe Description Attributes
Identifier Names: Private
Data Semantics: Private
Dependency Class: ISA
Argument Attributes
Identifier Names: Private
Data Semantics: Private
Dependency Class: ISA
Argument Types
None
969 syscall pread_nocancel entry
Probe Description Attributes
Identifier Names: Private
Data Semantics: Private
Dependency Class: ISA
Argument Attributes
Identifier Names: Private
Data Semantics: Private
Dependency Class: ISA
Argument Types
None
但论证是无。如何找到论点?
答案 0 :(得分:2)
您将参数的含义与参数的类型混淆。
参数的含义取决于提供者。如果您想了解syscall:::
探针,那么您需要查阅syscall provider的文档,其中说明了
<强>参数强>
对于入口探测器,参数(
arg0
..argn
)是参数 系统调用。对于返回探测,arg0
和arg1
都包含 回报价值。 D变量errno
中的非零值表示 系统调用失败。
因此在条款中
syscall::read:entry
{
...
}
,对应
ssize_t read(int fildes, void *buf, size_t nbyte);
,arg0
将是fildes
的值,arg1
将是buf
的值,arg2
将是nbyte
的值}。
arg0
,arg1
,arg2
等的类型始终为int64_t
,无论它们的参数类型如何代表。这对于标量是足够的,但对于结构,dtrace(1)需要理解类型。可以投射参数,例如
((struct mystruct *)(arg0))->my_member
但这很刺激。有时,但并非总是如此,DTrace知道参数本身的类型,并允许使用符号args[0]
,args[1]
等来描述它们。因此,在某些情况下,我可以改为编写更方便的
args[0]->my_member
对于系统调用提供程序,DTrace 不知道参数的类型,这就是你看到的原因
# dtrace -lv -n syscall::read:entry
...
Argument Types
None
#
以及为什么
dtrace -n 'syscall::read:entry {trace(args[0])}'
无效。
但是,对于io提供程序,DTrace 知道参数的类型,例如
# dtrace -lv -n io:::start
...
Argument Types
args[0]: bufinfo_t *
args[1]: devinfo_t *
args[2]: fileinfo_t *
#
通过阅读documentation for the io provider可以看到bufinfo_t
的定义包括
typedef struct bufinfo {
...
size_t b_bcount; /* number of bytes */
...
} bufinfo_t;
这允许人们写,例如
dtrace -n 'io:::start {trace(args[0]->b_bcount)}'.
最后,你提到fds[]
。正如我解释before,fds[n]
的类型是fileinfo_t *
。
我建议您遵循此introduction。
答案 1 :(得分:0)
man 2 read
怎么样?在Mac OS上,我明白了:
READ(2) BSD System Calls Manual READ(2)
NAME
pread, read, readv -- read input
LIBRARY
Standard C Library (libc, -lc)
SYNOPSIS
#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
ssize_t
pread(int d, void *buf, size_t nbyte, off_t offset);
ssize_t
read(int fildes, void *buf, size_t nbyte);
ssize_t
readv(int d, const struct iovec *iov, int iovcnt);
...
但这显然只适用于syscall
提供商。