dtruss
は、DTrace 用に作成されたスクリプトの洗練された例であると同時に、DTrace で実現できることのデモンストレーションでもあります。ただし、その類似性truss
はstrace
比較的不毛な OS X に非常に歓迎されていdtruss
ますが、いずれかの完全な代替を意図したものではなかったと思います。
いずれにせよ、あなたの質問は少しあいまいです: 表示される文字列が切り捨てられていることを懸念しているのか、 or の文字列がまったく表示されていないことを懸念しているのsendto()
かrecvfrom()
(DTrace によって明らかにされる基になるインターフェイス) はわかりません。私は両方に対処します。
まず、DTrace はカーネルでデータを収集します。ユーザーランドバッファーは、D 言語で取得されるcopyin()
かcopyinstr()
、記録されてコンシューマー (通常はdtrace(1)
コマンド) に送信される前に取得されます。DTrace では、カーネル バッファ サイズがコンパイル時にわかっている必要があるため、そうでなければ予測できない文字列の長さに制限を課します。この制限はデフォルトで 256 バイトです。切り捨てが発生している場合は、次のように追加して制限を変更できます。
#pragma D option strsize=512
以下はdtruss
既存のものpragma
です。
第 2 にdtruss
、さまざまなシステム コールのフォーマット要件を把握するためにハードコードされています。ソースで明示的に処理されないため、sendto()
またはその出力にバッファーの解釈は表示されません。recvfrom()
それらを追加するのに適した場所を見つけるのを止めるものは何もありませんが、代わりに独自のスクリプトを書くことができます:
bash-3.2# cat sr.d
#pragma D option rawbytes
syscall::sendto:entry,
syscall::recvfrom:entry
/pid == $target/
{
self->bufp = arg1;
self->size = arg2;
}
syscall::sendto:return,
syscall::recvfrom:return
/pid == $target && self->bufp && self->size/
{
printf("%s():\n", probefunc);
tracemem(copyin(self->bufp, self->size), 64);
printf("\n");
self->bufp = self->size = NULL;
}
bash-3.2# dtrace -qs ./sr.d -p 16988
sendto():
0 1 2 3 4 5 6 7 8 9 a b c d e f 0123456789abcdef
0: 68 65 6c 6c 6f 00 00 00 00 00 00 00 00 00 00 00 hello...........
10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
30: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................
^C
bash-3.2#
tracemem()
文字列に関しては、による DTrace のデータ記録バッファの使用に厳しい制限を設ける義務があることに注意してください。制限にほとんど近づかない場合、出力が圧倒され、ほとんどが冗長になるという苛立たしい結果が生じます。文字列を探していることがわかっている場合は、copyinstr()
代わりに単純に使用できます。私の OS X 10.6.8 よりも最新の DTrace 実装を使用している場合は、次のように記述できることがわかります。
tracemem(copyin(self->bufp, self->size), 64, self->size);
ここで、2 番目の引数は記録されるバイト数のハード リミットですが、表示されるバイト数はオプションの 3 番目の引数によって制限されます。
最後に、ユーザーランドアドレスはシステムコールへの入り口で記録されますが、出口でのみ使用されることに注意してください。これは、システム コールが必要に応じてデータをフォルトインできるようにする一般的なイディオムです --- DTrace 自体はそうしません。非常駐アドレスをトレースするように要求された場合、実行時にエラーが発生します。