2

我是 dtrace 的新手,正在尝试编写一些基本的 dtrace 脚本。我找到了一个在单独的终端上捕获 read(2) 和 write(2) 系统调用的示例,如下所示,

 syscall::read:entry,
 syscall::write:entry
 /pid==4217/
 {

 }

指定的 pid 号来自其他终端的 pid id。当我看到这个例子时,如果我用 dtrace 运行这个脚本,它应该会显示一些读写系统调用。但我只观察到读系统调用,但没有观察到写系统调用。

因此,如果我理解正确,在我观察到的终端(pid 4217)上,如果我在该终端上键入某些内容,内核将读取它的字符,因此假设会发生读取系统调用。如果我输入“ls”之类的内容并回车,内核将读取并执行它,并将一些输出写入终端,因此编写系统调用假设被调用。但我没有看到任何写入系统调用。这是为什么?

4

2 回答 2

1

我将首先验证 write() 是否适用于任何其他过程,例如一个简单的测试用例。在您的示例中,可能是(a)它的 pid 错误,或者它的孩子在写,或者(b)没有使用 write 调用,但可能是,例如 writev() 或其他一些调用(尝试使用验证strace 也许)。

于 2013-05-05T11:09:49.993 回答
0

我同意@PaulFox,这可能是一个错误的pid值。当终端在您按下回车之前暂停时,终端处于read系统调用的中间。但是,当它打印终端提示符时(在您按下回车键并ls运行之后),它会通过write系统调用来实现。请注意,输出ls不是write系统调用的来源!那pid将是正在运行的ls命令的进程 ID。

要测试write系统调用是否确实有效,请运行以下命令:

# dtrace -n 'syscall::write:entry {printf("hello")}'

然后用你的终端尝试它(用你正在使用的任何东西替换'bash')作为目标:

# dtrace -n 'syscall::write:entry /pid==$target/ {printf("hello")}' -c 'bash'

如果您在终端中输入内容时其中一个未能显示任何写入内容,请回发。

另请注意,您的 shell 可能正在使用多个版本的 write 系统调用(尽管如果它使用的不是普通的,我会感到惊讶write):

# dtrace -ln 'syscall::*write*:entry'
   ID   PROVIDER            MODULE                          FUNCTION NAME
  147    syscall                                               write entry
  381    syscall                                              writev entry
  447    syscall                                              pwrite entry
  777    syscall                                           aio_write entry
  933    syscall                                      write_nocancel entry
  963    syscall                                     writev_nocancel entry
  969    syscall                                     pwrite_nocancel entry
于 2013-05-30T00:03:49.253 回答