为什么syscall read参数为null?

时间:2014-01-01 13:57:09

标签: dtrace

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

但论证是无。如何找到论点?

2 个答案:

答案 0 :(得分:2)

您将参数的含义与参数的类型混淆。

参数的含义取决于提供者。如果您想了解syscall:::探针,那么您需要查阅syscall provider的文档,其中说明了

  

<强>参数

     

对于入口探测器,参数(arg0 .. argn)是参数   系统调用。对于返回探测,arg0arg1都包含   回报价值。 D变量errno中的非零值表示   系统调用失败。

因此在条款中

syscall::read:entry
{
    ...
}

,对应

ssize_t read(int fildes, void *buf, size_t nbyte);

arg0将是fildes的值,arg1将是buf的值,arg2将是nbyte的值}。

arg0arg1arg2等的类型始终为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[]。正如我解释beforefds[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提供商。