EGL デバッガーでのアプリケーションのステップスルー

このトピックでは、EGL デバッガーにおけるプログラムのデバッグの、基本的なステップについて説明します。

本書では、アプリケーションのデバッグの方針については詳述しませんが、 一般にデバッグ・プロセスにおいては、コード内の問題の原因を特定することが 中心となります。例えば、プログラムが異常終了した場合に、 デバッガーを使用してコードをステップスルーすることで、プログラム内で障害が発生している 場所を特定することができます。予期しない値がプログラムから出力される場合は、 デバッガーを使用して変数の値を追跡することで、予期しない値が出力されている 場所を特定することができます。

デバッガーがデバッグを開始する場所は、常にプログラム・パーツです。 他の論理パーツ (ライブラリーなど) をデバッグしたい場合は、 プログラムから対象の論理パーツにステップインする必要があります。 場合によっては、デバッグしたい論理パーツを呼び出す関数のみを持つ、 シンプルなプログラムを作成すると便利です。

前提条件

以下のサンプル・プログラムには、シンプルなエラーが含まれています。 これを使って、デバッガーのテストを行うことができます。
program myDebugTestPgm type BasicProgram 

  function main()

    //Provide some initial values for the array of items.
    customerItems items[3];
    customerItems[1].itemNumber=1;
    customerItems[2].itemNumber=2;
    customerItems[3].itemNumber=3;
    customerItems[1].itemCost=12.50;
    customerItems[2].itemCost=200;
    customerItems[3].itemCost=49.95;
    customerItems[1].itemQuantity=30;
    customerItems[2].itemQuantity=10;
    customerItems[3].itemQuantity=60;

    counter int;
    orderTotal float=0;

    //Calculate the total cost of the items.
    //Use the discountPrice function to get the discounted cost of each item.
    for (counter from 1 to customerItems.getSize() by 1)
      orderTotal += discountPrice(customerItems[counter].itemCost, 
                                  customerItems[counter].itemQuantity);
    end // for loop

    //Write the output to the console.
    SysLib.writeStderr("The total cost for the order is $" + orderTotal);
  end // main

  //Return a total price for a group of items 
  //based on the item price and a quantity discount.
  function discountPrice(itemCost float in, itemQuantity int in) returns(float)
    discountRate float=0;
    quantCost float=0;

    //Determine the discount for each quantity.
    //Discount 20% for more than 50 items.
    //Discount 5% for more than 20 items.
    case
      when (itemQuantity > 50)
        discountRate = 1/5;
     when (itemQuantity > 20 && itemQuantity <= 50)
       discountRate = 1/20;
     otherwise
       //bug - division by zero
       discountRate = 1/0;
     end

    //Multiply the cost of the item, the number of items, 
    //and the discounted price.
    quantCost = itemCost*itemQuantity*(1-discountRate); 
    quantCost = MathLib.round(quantCost, -2);

    return (quantCost);
  end // function discountPrice

end // program

record items type BasicRecord
  itemNumber    int;
  itemCost      float;
  itemQuantity  int;
end
このプログラムを生成して実行すると、EGL は 、discountPrice 関数と 1/0 式をポイントしたエラーを返します。 今回のケースでは、エラーの特定は簡単ですが、 これほど容易にエラーを検出できないケースもあります。 エラーの原因を特定する場合、最初のステップとして、 デバッガーでブレークポイントを設定してプログラムを実行し、 プログラムで障害が発生する箇所の特定を行います。

ブレークポイントの追加

コード内の 1 つ以上の行に ブレークポイント のマークを付けることができます。デバッガーがブレークポイントに到達すると、関連するコード行を実行する前に一時停止します。ユーザーは、 デバッガーに次の実行を指示する前に、プログラム変数の現行値をチェックすることができます。 ブレークポイントは、デバッグ・プロセスの実行時にのみ使用され、 生成されたソースにはいかなる影響も及ぼしません。

ブレークポイントを追加するには、EGL エディター内で、コードの左側にあるグレーの余白部をダブルクリックします。 前出の例では、エラー・メッセージによって discountPrice 関数でエラーが発生していることが通知されているため、この関数全体にブレークポイントを設定することが必要となります。 ブレークポイントは、このグレーの余白部に青色の円でマークされます。

コード内のブレークポイントを示す、青色の円の画像

ブレークポイントは、ロジックを実行する EGL コード行の大半に追加できます。例えば、以下のとおりです。
  • assignment ステートメント。例:
    myString = "Hello";
  • 代入を含む変数宣言。例:
    myInt int = 5;
  • システム関数または EGL 関数の呼び出し。例:
    SysLib.writeStderr("Hello");
  • ループまたは比較ステートメント。例:
    if (myInt == 5)
ただし、以下のようなコード行には、ブレークポイントを追加できません。
  • 代入が含まれない変数宣言
  • end ステートメント
  • functionprogrampackage で始まるコード行、または論理パーツを宣言するその他の行。 ただし、各プログラムの最初の行については、 ブレークポイントが設定されている行と同じように扱うよう、デバッガーを設定することができます。 EGL デバッガーの設定の変更を参照してください。
  • データ・パーツ内にある行すべて
  • ブランク行、またはコメントのみで構成されている行

ブレークポイントの詳細な使用方法については 、EGL デバッガーでのブレークポイントの使用を参照してください。

ブレークポイントを使用せずに、プログラムをデバッグすることもできます。 「ウィンドウ」 > 「設定」 > 「EGL」 > 「デバッグ」 > 「プログラムの先頭行で停止」の設定にチェックマークを付けると、プログラムの main() 関数内の最初の実行可能行に、ブレークポイントを設定した場合と同じ意味になります。 このポイントから、後続のコード行をステップスルーまたは迂回 (1 行実行するごとに一時停止) することができます。ステップ・コマンドについての詳細は、EGL デバッガーのコントロールを参照してください。

EGL デバッガーでのプログラムの実行

プログラムに ブレークポイントを追加するか、「先頭行で停止」オプションを設定した後に (このトピック内の『ブレークポイントの追加』(前述) を参照)、プログラムをデバッガーで実行できます。

デバッガーでは、アプリケーションをどのように実行するかを記述した 起動構成が必要です。 起動構成は、次の 2 つの方法で作成できます。 ほとんどのプログラムでは、自動作成した起動構成を使用できます。
  1. 「プロジェクト・エクスプローラー」ビューで、デバッグ対象の EGL ソース・プログラムを右クリックしてから、 「デバッグ」 > 「EGL プログラム」とクリックします。デバッガーは、 以下のタスクを実行します。
    • プログラムの起動構成が存在しない場合、デバッガーはデフォルトの起動構成を 作成します。「実行」 > 「デバッグ」とクリックすると、この構成を表示できます。
    • ワークベンチの設定に応じて、 デバッガーはデバッグ・パースペクティブに自動的に切り替えるか、 ユーザーにデバッグ・パースペクティブへの切り替えを求めるプロンプトを表示します。 パースペクティブの切り替えは、手動でも行えます。 「ウィンドウ」 > 「パースペクティブを開く」 > 「その他」 > 「デバッグ」と選択してください。
    • デバッガーが、プログラムの実行を開始します。
  2. デバッガーがプログラムの実行を開始した後は、ブレークポイントに到達するか、または実行可能コードの最初の行を検出する (このオプションを設定している場合) まで、 プログラムの実行を継続します。このポイントに到達すると、デバッガーは一時停止して、 以下の情報を表示します。
    • 次に実行される行が、EGL エディターで強調表示されます。
    • 変数ビューには、現在の論理パーツ内の すべての変数の値 (システム変数の値を含む) が表示されます。このビューを使用して、 プログラム全体を通じて変数の値を追跡できます。デバッガーが ブレークポイントで一時停止している間に、変数の値を変更することもできます。
    • デバッグ・ビューには、現在の実行単位内で実行中のスレッドがリストされます。 つまり、このビューに表示されるのは、現在実行中のプログラムまたは論理パーツということになります。 このビューを使用して、デバッグ・プロセスの再開または停止を行います。
    • ブレークポイント・ビューには、プログラム内のブレークポイントがリストされます。このビューでブレークポイントのチェック・ボックスをクリアすると、 そのブレークポイントを一時的に無効にすることができます。
  3. デバッガーに処理を続行させる場合は、デバッグ・ビューの上部にある「再開」ボタンをクリックします。 デバッガーは、次のブレークポイントまで続行します。 また、「ステップ」ボタンのいずれかを使用することで、 プログラムを次の行まで実行させてから、再び一時停止させることもできます。

    このサンプル・プログラムでは、 デバッガーが discountRate = 1/0; の行に到達するまで、 ブレークポイントから次のブレークポイントまでプログラムを実行できます。 デバッガーがこの行に到達すると、 プログラムの実行時にコンソールに表示されるものと同じエラーを返します。

  4. デバッグが完了したら、「デバッグ」ビューの上部にある「強制終了」ボタンをクリックして、デバッガーを停止させます。または、「再開」ボタンをクリックして、完了するまでプログラムを実行させることもできます。

フィードバック