2

私は dtrace を初めて使用し、基本的な dtrace スクリプトを作成しようとしています。次のように、別の端末で read(2) および write(2) システムコールをキャッチする例を見つけました。

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

 }

指定された pid 番号は、他の端末の pid id からのものです。この例を見たとき、このスクリプトを dtrace で実行すると、読み取りと書き込みの syscall が表示されるはずでした。しかし、私は read syscall だけを観察しましたが、write syscall は観察しませんでした。

したがって、私が正しく理解している場合、私が観察した端末(pid 4217)で、その端末で何かを入力すると、カーネルはその文字を読み取るため、syscall が発生したと想定されます。「ls」のようなものを入力してEnterキーを押すと、カーネルがそれを読み取って実行し、出力を端末に書き込むため、write syscallが呼び出されると想定されます。しかし、どういうわけか書き込みシステムコールが表示されません。何故ですか?

4

2 に答える 2

1

最初に、単純なテストケースなど、他のプロセスで write() が機能することを検証します。あなたの例では、(a)間違ったpid、または子が書き込みを行っている、または(b)書き込み呼び出しが使用されていない可能性がありますが、たとえば、writev()またはその他の呼び出し(で検証してみてくださいstrace かもしれません)。

于 2013-05-05T11:09:49.993 に答える
0

@PaulFoxに同意します。これはおそらく間違ったpid値です。Enter キーを押す前に端末が一時停止している場合、端末はシステムコールの最中ですread。ただし、(Enter キーを押して実行した後) ターミナル プロンプトを出力するときは、 syscalllsを作成して実行します。からの出力は、システムコールの発信元ではないwriteことに注意してください! これは、実行中のコマンドのプロセス ID になります。lswritepidls

writesyscall が実際に機能していることをテストするには、次を実行します。

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

次に、ターゲットとして端末で試してください(「bash」を使用しているものに置き換えます):

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

そして、端末に何かを入力しているときに、それらのいずれかが書き込みを表示しない場合は、投稿してください。

また、シェルが使用している可能性のある write syscall にはいくつかのバージョンがあることに注意してください (ただし、通常の 以外のものを使用した場合は驚くでしょう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 に答える