Skip to main content

IAR Embedded Workbench for Arm 9.70.x

アプリケーション実行の概要

このセクションの内容:

C-SPY では、アプリケーションの実行をモニタおよび制御することができます。シングルステップでアプリケーションを実行し、ブレークポイントを設定することにより、変数やレジスタの値など、アプリケーション実行の詳細を調べることができます。また、コールスタックを使用して、関数のコールチェーン内でステップの前後を調べることもできます。

ターミナル I/O およびデバッグログ機能を使用すると、アプリケーションを操作できます。

そのようなコマンドは、[デバッグ]メニューとツールバーにあります。

C-SPY では、必要に応じてソースモードと逆アセンブリモードを切り替えてデバッグできます。

ソースモードのデバッグは、アプリケーションを短期間で簡単に開発するための手段であり、コンパイラやアセンブラがどのようにコードを実装したかを知る必要はありません。エディタウィンドウでは、一度に 1 ステートメントずつアプリケーションを実行しながら、変数やデータ構造体の値をモニタできます。

逆アセンブリモードのデバッグでは、アプリケーションの重要なセクションに焦点を当てて、アプリケーションコードを高い精度で制御できます。逆アセンブリウィンドウを開くと、アプリケーションが、ソースコードではなく実際のメモリの内容に基づいて、ニーモニックアセンブリリストとして表示され、一度にひとつのマシン命令をアプリケーションで実行できます。

どちらのモードでデバッグしている場合でも、レジスタとメモリを表示したり、その内容を書き換えたりすることができます。

C-SPY はステートメント単位でステップを実行できるため、行単位でステップを実行する他の多くのデバッガよりも高い精度でステップ実行できます。コンパイラは、文や関数呼び出しごとにステップポイントという形式で詳細なステップ実行情報を生成します。すなわち、コマンドでステップインするか、ステップオーバするかを選択する可能性のあるソースコード上の位置に、ステップポイントを生成します。ステップポイントはステートメントだけでなく、関数呼び出しの位置にも生成されるので、単純にステートメントをステップ実行するよりも詳細にステップ実行できます。

ステップ実行が低速になる要素はいくつかあります。速度が遅すぎると感じる場合は、ステップ速度が遅いときのトラブルシューティングのヒントを参照してください。

ステップコマンド

ステップコマンドには、以下の 4 つのコマンドがあります。

  • ステップイン

  • ステップオーバ

  • 次のステートメント

  • ステップアウト

[自動ステップの設定]ダイアログボックスを使用して、シングルステップの実行を自動化できます。詳細については、[自動ステップの設定]ダイアログボックスを参照してください。

コード外部で検出される例外(通常はステップの一部として実行されます)がアプリケーションに含まれる場合、C-SPY はcatch 文の位置でステップを終了します。

以下に示す例で、1 つ前のステップ実行の結果、現在f(i)関数呼び出し(強調表示)の位置にいるものとします。

extern int g(int);
int f(int n)
{
 value = g(n-1) + g(n-2) + g(n-3);
 return value; 
}
int main()
{
  ...
  f(i);
  value ++;
}
ステップインStepIntoButton_Mym80_02.png

ステップ実行中は、通常は関数にステップインして関数かサブルーチンの内部でステップ実行を継続することを考えます。[ステップイン]コマンドを実行すると、サブルーチンg(n-1)内部の最初のステップポイントに移動します。

extern int g(int);
int f(int n)
{
 value = g(n-1) + g(n-2) + g(n-3);
 return value;
}

[ステップイン]コマンドは、通常の制御の流れに従い、次のステップポイントが同じであるか別の関数であるかどうかに関わらず、次のステップポイントまで実行します。

ステップオーバStepOverButton_Mym80_02.png

[ステップオーバ] コマンドは、同じ関数の次のステップポイントまで実行します。呼び出された関数の内部にステップインすることはありません。上の例でステップオーバを実行すると、g(n-2)関数呼び出しまで実行します。この関数呼び出しは独立したステートメントではなく、g(n-1)と同じしてーとメントにあります。このようにして、ステートメントの一部に興味のない関数呼び出しがある場合にそこをスキップして、重要な部分だけをデバッグすることができます。

extern int g(int);
int f(int n)
{ 
 value = g(n-1) + g(n-2) + g(n-3);
 return value;
}
次のステートメントNextStatementButton_Mym80_02.png

[次のステートメント] コマンドは、この場合の次のステートメントであるreturn valueまで一気に実行します。

extern int g(int);
int f(int n)
{
 value = g(n-1) + g(n-2) + g(n-3);
 return value;
}
ステップアウトStepOutButton_Mym80_02.png

関数内部では、必要に応じて、[ステップアウト] コマンドを実行すると、関数の最後に到達する前に、関数からステップアウトすることができます。これによって、関数呼び出しの直後のステートメントまで一気に実行します。

extern int g(int);
int f(int n)
{
 value = g(n-1) + g(n-2) g(n-3);
 return value;
}
int main()
{
  ...
  f(i);
  value ++;
}

複雑なステートメントの一部である個別の関数にステップインできる機能は、複数回ネストしている関数呼び出しを含む C ソースコードを使用している場合に、特に役に立ちます。また、コンストラクタ、デストラクタ、代入演算子、その他のユーザ定義演算子など、多くの間接的な関数呼び出しを使用する傾向がある C++ でも、ステップイン機能が非常に役に立ちます。

細かいステップ実行は、状況によっては役立つ場合もありますが、不必要に処理を遅くすることもあります。そのため、ステートメント単位でステップ実行する機能があり、これによって高速なステップ実行が可能になります。

ステップ速度が遅いと感じる場合、次のトラブルシューティングのヒントがステップの加速化に役立つことがあります。

  • ハードウェアデバッガシステムを使用している場合、使用されているハードウェアブレークポイントの数を把握して、そのうちいくつかがステップ用に残っているようにします。

    C-SPYでのステップ実行は通常、ブレークポイントを使用して行われます。C-SPYがステップコマンドを実行する際、次のステートメントにブレークポイントが設定されて、このブレークポイントに達するまでアプリケーションが実行されます。ハードウェアデバッガシステムを使用する場合、ハードウェアブレークポイントの数は限られています。通常これらは、フラッシュ/ROMメモリに配置されたコード内にステップブレークポイントを設定するために使用されます。たとえば、Cswitchの文にステップインする場合、ブレークポイントは各分岐に設定されます。これによって、いくつかのハードウェアブレークポイントが使用されます。使用可能なハードウェアブレークポイントの数に達した場合、C-SPYはアセンブリレベルでのシングルステップに切り替わり、速度が非常に低下する可能性があります。

    詳細については、C-SPYハ ードウェアデバッガドライバのブレークポイントブレークポイントの消費元を参照してください。

  • [トレース] ウィンドウおよび[関数プロファイリング]ウィンドウの[有効化/無効化]ボタンを使用して、トレースデータの収集を無効にします。トレースデータの収集によって、ステップ実行が遅くなることがあります。これは収集されたデータが各ステップの後に処理されるためです。トレースデータの収集を無効にするには、対応するウィンドウを閉じるだけでは不十分な点に注意してください。

  • SFRレジスタの限定された選択内容のみを表示するときに選択します。以下の2つのどちらかを選択します。[ウォッチ]ウィンドウに#SFR_name (SFR_nameはモニタするSFR名)と入力するか、[レジスタ]ウィンドウに限られたグループのSFRを表示する独自のフィルタを作成します。多くのSFRレジスタを表示すると、ステップの実行が遅くなることがあります。これは各ステップの後にすべてのレジスタをハードウェアから読み取らなければならないためです。アプリケーション固有のレジスタグループの定義を参照してください。

  • [メモリ]ウィンドウと[シンボルメモリ] ウィンドウが開いていれば閉じます。これは、各ステップの後に表示されているメモリを読み取らなければならず、そうなるとステップ実行が遅くなる可能性があるためです。

  • [ウォッチ][ライブウォッチ][ローカル][静的] など、式が表示されるウィンドウが開いていれば閉じます。これは、これらのウィンドウで各ステップの実行後にメモリが読み込まれて、ステップの実行が遅くなる可能性があるためです。

  • [スタック]ウィンドウが開いていれば閉じます。[ツール]>[オプション]>[スタック]を選択して、[グラフィカルスタック表示とスタック使用トラッキングを有効にする]オプションが有効になっていれば無効にします。

  • 可能であれば、C-SPYとターゲットボード/エミュレータ間の通信速度を上げます。

実行 GoButton_Mym80_02.png

[実行]コマンドは、現在の位置からブレークポイントまたはプログラムの最後に到達するまで、続けて実行します。

注記

対称マルチコアデバッグを使用している場合は、[実行]コマンドはフォーカスされているコアだけを開始します。

強調表示RunToCursorButton_Mym80_02.png

[カーソルまで実行]コマンドは、ソースコードの現在カーソルのある位置まで実行します。[カーソルまで実行]コマンドは、[逆アセンブリ]ウィンドウと[コールスタック]ウィンドウでも使用できます。

エディタウィンドウと[逆アセンブリ]ウィンドウの両方で実行を停止するたびに、C-SPY は対応する C/C++ ソースまたは命令を緑色で強調表示します。さらに緑色の矢印が、C/C++ ソースレベルでステップする場合はエディタウィンドウに、逆アセンブリレベルでステップする場合は[逆アセンブリ]ウィンドウに表示されます。これは、どのウィンドウがアクティブであるかによって決まります。アクティブなウィンドウがない場合、最後にどのウィンドウがアクティブだったかによって決まります。

CShighlight.png

関数呼び出しのない単純な文の場合、通常は文全体が強調表示されます。複数の関数呼び出しを含む文で停止した場合、[ステップイン][ステップオーバ]の違いを明確に表すために、最初の関数呼び出しが強調表示されます。

ときどき、ソースウィンドウのステートメントが通常の強調表示よりも薄い色で強調表示される場合があります。これは、プログラムカウンタはソース文を構成するアセンブラ命令を指していても、そこが正確なステップポイントではないことを意味します。これは、[逆アセンブリ]ウィンドウでステップ実行しているときによく発生します。プログラムカウンタがソース文の最初の命令を指している場合は、通常の強調表示色が使用されます。

コードカバレッジ

コードカバレッジウィンドウのコンテキストメニューから、ソースコードのコードカバレッジ解析を表示するエディタウィンドウのハイライトカラーとアイコンを変更できます。コードカバレッジ ウィンドウを参照してください。

使用されるカラーとアイコンを次に示します。

  • 赤のハイライトカラーと赤色のひし形— コード範囲は実行されていません。

  • 緑のハイライトカラー—コード範囲の100%が実行されています。

  • 黄色のハイライトカラーと赤色のひし形—一部のコード範囲が実行されています。

この図には、3 つのすべてのコードカバレッジのハイライトカラーを示します。

CodeCoverInEditorWin_Mym83_01.png

コンパイラは、詳細なコールフレーム情報を生成します。これにより、C-SPY は、実行に影響を及ぼすことなく、いつでも関数コールチェーン全体を表示できます。

ヒント

通常、これは次の 2 つの目的に役立ちます。

  • 現在の関数の呼び出し元のコンテキストを決定する場合

  • 不正な変数やパラメータの値を検出したときに、その発生元をトレースして、コールチェーン内で問題が発生した関数を特定する場合

[コールスタック] ウィンドウには関数呼び出しのリストが表示され、現在の関数が一番上になります。コールチェーンの関数を調べるときに、影響を受けたすべてのウィンドウの内容が更新され、特定のコールフレームの状態が表示されます。[ローカル][レジスタ][ウォッチ][逆アセンブリ] の各ウィンドウがあります。通常、関数がすべてのレジスタを使用することはないため、一部のレジスタは状態が未定義であり、そのときはダッシュ記号(‑‑-)で表示されます。

エディタウィンドウと[逆アセンブリ] ウィンドウでは、最上位または現在のコールフレームは緑色で強調表示され、他のフレームを検証しているときは黄色で強調表示されます。

コールスタックで関数を選択し、[カーソル位置まで実行] コマンドをクリックしてその関数を実行すれば便利です。

アセンブラソースコードには、自動的にコールフレーム情報が挿入されることはありません。適切なCFIアセンブラディレクティブをアセンブラソースコードに追加すると、アセンブラモジュールのコールチェーンも表示できるようになります。詳細については、『コールフレームの使用の追跡』を参照してください。

注記

非常に最適化されたコードの場合、C-SPY はすべてのコールを識別できない場合があります。これは、非常に最適化されたコードの場合コールスタックは全体的に信頼できないということです。

場合によっては、stdinstdoutを使用するアプリケーションの構文を、実際のハードウェアデバイスを入出力として使用しないでデバッグする必要があります。[ターミナル I/O]ウィンドウでは、アプリケーションに入力したり、アプリケーションからの出力を表示したりできます。また、[ターミナルI/O ログファイル]ダイアログボックスを使用して、ターミナル I/O をファイルに出力することもできます。

ヒント

この機能は、以下の 2 つのコンテキストで使用します。

  • アプリケーションがstdinstdoutを使用している場合

  • デバッグトレース出力を生成する場合

詳細については、ターミナル I/O ウィンドウ[ターミナル I/O ログファイル]ダイアログボックスを参照してください。

[デバッグログ]ウィンドウには、診断メッセージやマクロにより生成された出力、トレースについての情報など、デバッガの出力が表示されます。

ヒント

これらの情報は、簡単に検証できるファイルにログとして記録しておくと便利です。デバッグログウィンドウを参照してください。デバッガの出力をファイルに記録することで、主に 2 つのメリットがあります。

  • ファイルをエディタなどの別のツールで開くことができるので、ファイルの中で特に興味のある部分だけ調べることが可能。

  • ファイルには、どこでブレークポイントがトリガされたかなど、プログラム実行がどのように制御されたかの履歴が残る。