2016-07-08 10 views
0

私はstraceを使用して、Erlang VMがどのようにwritevを使用しているかを理解しようとしています。私はシステムコールについてはほとんど知りません。私が見ていることを理解しようとしています。 this article`writev`の呼び出しでメモリアドレスが表示されないのはなぜですか?

、著者は、ファイルへの書き込み小さなErlangのプログラムをトレースし、このようにシステムコールを見ての例を示します。

writev(0x1A, 0x1A5405F8, 0x4) 

彼はwritevが与えられていることを説明するために行きますいくつかのより多くのメモリアドレスを含むベクトルのメモリアドレス。おそらくオペレーティングシステムはそれらのアドレスからデータを取り出し、それをファイルに入れます。

私は自分自身が著者の一例を試してみました - (Ubunto 12.04 VMに)iexと呼ばれるエリクシールREPLで同じコードを実行すると、このようにそれをトレース:

# show me system calls for process 1166... 
# ... and show long output if necessary (the -s flag) 
# ... and also trace any child processes (the -f flag) 
# ... and I only care about calls to writev (the -e flag) 
# ... and capture standard error to a file (the >(tee ...)) 
strace -p 1166 -s 99999 -f -e writev 2> >(tee syscalls.txt) 

しかし、私が得た出力は次のようになります:「19バイトの合計は、次の4列、その長さと記載されているそれぞれの書き込み、記述子11を提出する。」:

writev(11, [{"Hello ", 6}, {"&", 1}, {"amp;", 4}, {" Goodbye", 8}], 4) = 19 

私はこれを読ん

しかし、なぜメモリアドレスの代わりに実際の文字列値が表示されますか?それは、データがアドレスで参照されるのではなく何らかの形でコピーされていることを暗示しているのですか?

straceこのプロセスを実行すると、メモリアドレスがwritevになるのはなぜですか。

答えて

1

straceはますます良くなっています。今や、一時的な配列アドレスをログアウトするのではなく、実際に何が書き込まれているかを伝えます。これにより、ログに有用な情報が残ります。

あなたは-e verbose=!writevで冗長性をオフに反転するstraceのためにフラグをfutzing試すことができます - 多分引用する必要は注意がおよび/またはあなたのシェルに応じて、!を逃れる - (おそらくちょうどあなたの短命アレイアドレスをあなたに戻って得られます、あなたが引用した例のように)-e raw=writevで生の表示をひっくり返し、あなたが得るものを見てください。

また、デバッガを接続してwritevコールを傍受することもできます。これにより、プロセスからカーネルに送信されるデータを覗き込んで調べることができます。 (dtraceのような動的トレースユーティリティがあれば、世界を止めることなく同様のことができます)

+0

恐ろしいです!はい、 'strace -p 1166 -s 99999 -f -e 'でメモリアドレス出力を取得しています。verbose =!writev' -e 'raw = writev' -e 'trace = writev' 2>>(tee syscalls.txt ) ' –

関連する問題