機械翻訳について

制御フローのための述語の使用

実行時の安全性を確保するため、DとCやC++などの他のプログラミング言語の主な違いの1つとして、Javaプログラミング言語に、if文やループなどの制御フロー構造がないことがあげられ。 Dプログラム節は、固定量のデータ(オプション)をトレースする単一の直線的な文のリストとして作成されます。 Dは、述語と呼ばれる論理式を使用して、条件付きでデータをトレースし、制御フローを変更する機能を提供します。 このチュートリアルでは、Dプログラムの制御に述語を使用する方法を示します。

述語の動作を理解するために、10秒カウントダウン・タイマーを実装するDプログラムを作成します。 このプログラムを実行すると、10からカウント・ダウンし、メッセージを出力して終了します。 このプログラムでは、変数と述語を使用して、経過時間と出力内容を評価します。

  1. このプログラムの論理フローを設計します。

    プログラム自体を記述する前に、プログラムの論理フローを設計することを検討してください。 フローが明確に定義されていると、条件の構造を個別の節と述語に変換できます。 プログラムの論理フローは次のようになります:

    i = 10
    once per second,
      if i is greater than zero
        trace(i--);
      if i is equal to zero
        trace("blastoff!");
        exit(0);

    述語と関数が異なる同じプローブ記述の節を2つ作成することで、このプログラムに必要な論理フローを実現できます。

  2. プローブの起動時に、指定されたプローブ記述の関数の実行を許可するかどうかを決定するために、述語を使用したプログラム・コードを記述します。

    次に、プログラムのソース・コードを示します。 このコードをコピーして、countdown.dという名前のファイルに保存します。

    dtrace:::BEGIN 
    {
      i = 10;
    }
    
    profile:::tick-1sec
    /i > 0/
    {
      trace(i--);
    }
    
    profile:::tick-1sec
    /i == 0/
    {
      trace("blastoff!");
      exit(0);
    }
  3. プログラムを実行します。
    sudo dtrace -s countdown.d

    次のような出力が表示されます。

    dtrace: script 'countdown.d' matched 3 probes
    CPU     ID                    FUNCTION:NAME
      0    638                       :tick-1sec        10
      0    638                       :tick-1sec         9
      0    638                       :tick-1sec         8
      0    638                       :tick-1sec         7
      0    638                       :tick-1sec         6
      0    638                       :tick-1sec         5
      0    638                       :tick-1sec         4
      0    638                       :tick-1sec         3
      0    638                       :tick-1sec         2
      0    638                       :tick-1sec         1
      0    638                       :tick-1sec   blastoff!       
    #

このチュートリアルでは、BEGINプローブを使用して、変数整数iをカウントダウン開始の10に初期化します。 次に、tick-1secプローブを使用して、プログラムに毎秒1回起動するタイマーを実装します。 countdown.dでは、tick-1secプローブ記述が、述語と関数リストの異なる2つの個別の節で使用されています。 述語は、前後をスラッシュ//で囲まれた論理式で、プローブ名と、節の文リストが入っている中カッコ{}の間にあります。

最初の述語は、iがゼロより大きいかどうか(タイマーがまだ実行中かどうか)をテストします。

profile:::tick-1sec
/i > 0/
{
  trace(i--);
}

関係演算子>は、「より大きい」を意味し、偽の場合は整数値0、真の場合は1を返します。 iがまだ0になっていない場合、スクリプトではiをトレースし、--演算子を使用して1ずつ値を減らします。

2番目の述語は、==演算子を使用して、iが0 (カウントダウンが完了した)の場合に真を返します。

profile:::tick-1sec
/i == 0/
{
  trace("blastoff!");
  exit(0);
}

2番目の節では、文字列定数と呼ばれる二重引用符で囲まれた一連の文字にtrace関数を使用して、カウントダウンが完了したときの最後のメッセージを出力します。 次に、exit関数を使用して、すべてのトレースを終了し、最終的なデータの消費、集積体の出力(必要な場合)、シェル・プロンプトに戻る前のクリーン・アップの実行などの残りのタスクを実行します。

例1-1 あるプロセスIDのシステム・コールを監視するために述語を使用する方法

あるプロセスIDのシステム・コールをトレースするDプログラムを作成するには、述語を使用して、トレースするプロセスIDと一致するようにデフォルトのトレース関数を制限します。

syscall:::entry
/pid == 2860/
{
}

この例では、組込み変数pidが特定のID(この例では2860)と一致するように評価されます。 さらに、このスクリプトはシェルのマクロ変数を利用するように変更すると、拡張性が向上して、実行時に任意のプロセスIDに対して実行できるようになります。 次のようにスクリプトを編集し、strace.dsというファイルに保存します:

#!/usr/sbin/dtrace -s

syscall:::entry
/pid == $1/
{
}

ファイル・モードを変更して、実行可能にします。

sudo chmod +x strace.ds

これで、このスクリプトを使用して、システムでいずれかのプロセスによって行われたすべてのシステム・コールを監視できます。 たとえば、このスクリプトを実行して、cronデーモンによるシステム・コールを監視できます:

sudo ./strace.ds $(pidof /usr/sbin/crond)