このセクションでは、C/C++test を使って実行時エラー検出を行う方法について説明します。このセクションの内容:

概要

C/C++test の実行時エラー検出機能を利用すると、メモリ リーク、NULL ポインター、未初期化メモリ、バッファー オーバーフローといった重大な実行時のエラーをユニット レベルまたはアプリケーション レベルで特定することができます。  実行時エラー検出は、エンタープライズ開発にも組み込み開発にも適しています。 

この実行時エラー検出機能は柔軟であるため、たとえば組込みシステムのような標準ではないメモリ 割り当てモデルを使用している場合でも、実行時のメモリ解析を行うことができます。また、実行時 エラーを検出するためのインストゥルメントは軽量であるため、ターゲット基板、シミュレーター、 またはホスト上で組込みテストを実行できます。 

収集された問題は、問題の理解と解決に必要な詳細情報と共にレポートされます (メモリ ブロック サイズ、配列インデックス、割り当て/解放のスタック トレースなど)。カバレッジ メトリクスが追跡され、ユーザーがテスト作業の範囲を計測して増加するのに役立ちます。

アプリケーション レベルでの実行時エラー検出

アプリケーションの実行に対して実行時エラー検出を行うには、次の操作を行います。

  • [Application Monitoring] グループのビルトイン テスト コンフィギュレーションのいずれかを実行します (たとえば [Application Monitoring] > [Build and Run Application with Memory Monitoring] など)。 詳細については 「Application Monitoring グループ」 を参照してください。

C/C++test は、インストゥルメントしたアプリケーション実行ファイルを作成して実行します。選択されたコンフィギュレーションに応じて、カバレッジ 統計およびアプリケーション実行中に発見されたメモリ エラーのどちらか、あるいは両方がレポートされます。 

重要な注意事項

ビルドすると実行ファイルになるプロジェクトの場合、実行時エラー検出によってアプリケーションの実行を監視することができます。ライブラリ プロジェクトを監視するには、main() 関数の定義のコードをプロジェクトに追加する必要があります。このコードは、テスト対象ライブラリの使用シナリオの一部をシミュレートします。たとえば、#ifdef PARASOFT_CPPTEST を使ってテスト対象のライブラリ ソース ファイルにそのような main() 関数を追加することができます。

単体テスト実行中の実行時エラー検出

単体テストの実行中に実行時エラーを検出するには、次の操作を行います。

  • [Unit Testing] > [Run Unit Tests with Memory Monitoring] テスト コンフィギュレーションを実行します。

実行時メモリ解析が有効な状態でテスト用実行モジュールが生成され、テストが実行されます。テストの実行が完了すると、通常の単体テストのタスクに加えて、メモリの問題がレポートされます。

実行時エラーの検出のタスクは、それぞれルールの違反として次の場所にレポートされます。違反メッセージ、場所、およびスタック トレースがレポートされます。

  • GUI の [品質タスク] ビュー
  • GUI のコード エディター
  • C/C++test コンソール (GUI での実行とコマンドラインでの実行の両方)
  • テスト実行の後に生成されるレポート

実行時エラー検出の違反の抑制

静的解析の違反と同じように、実行時エラー検出の違反も抑制することができます。GUI から抑制するか、または // parasoft-suppress <ruleid> ["<reason>"] を使ってソース コードから抑制できます。

詳細については 「静的解析違反メッセージの抑制」 を参照してください。

実行時エラー検出オプションのカスタマイズ

テスト コンフィギュレーションでオプションを変更して、実行時エラー検出の動作をカスタマイズすることができます。

[実行] > [全般] タブでは次のオプションを設定できます。

  • 実行モード (単体テストまたはアプリケーション検証): 単体テストを実行するときに実行時エラー検出を行うか、それともアプリケーションをビルドして実行するかを指定します。なお、アプリケーションのビルドと実行ではテスト ケースは生成されません。
    • アプリケーション検証モードの場合、アプリケーション バイナリの場所と名前 (Test application binary) および実行コマンドライン (Application command line) を指定することもできます。
  • テスト実行フロー
    • アプリケーション検証モードの場合、テスト実行フローの [Build application executable] または [Build and run application executable] を使用できます。
    • 単体テスト モードの場合、標準またはカスタムの単体テスト実行フローを使用できます。詳細については、「テスト実行フローのカスタマイズ」 を参照してください。
  • インストゥルメント モード
    • アプリケーション検証モードの場合、[アプリケーションの完全監視]、[アプリケーション メモリ エラー チェック]、および [アプリケーション カバレッジの監視] を使用できます。
    • 単体テスト モードの場合、[行カバレッジ計測とメモリ エラー検出] を使用できます。

[実行] > [実行時] タブでは次のオプションを設定できます。

  • テスト用実行モジュールの実行ディレクトリ: 単体テスト モードとアプリケーション検証モードの両方について、テスト用実行モジュールを作成して実行する場所を指定します。テスト ケースのソースまたはテスト対象のコードで相対パスが使用されている場合、C/C++test はこのディレクトリ内でファイルを検索します。

実行時エラー検出のルール

テスト対象のコードに対してメモリ関連の問題を発見するために、C/C++test には次の実行時エラー検出ルールが用意されています。

ルール ID説明
RUN-MEM-DANG

ダングリング ポインターを使用してメモリにアクセスしない

このルールは、すでに解放済みのメモリを指すポインターの使用に関する問題を検出します。

RUN-MEM-WILD

ワイルド ポインターを使用してメモリにアクセスしない

このルールは、有効なメモリ バッファーを指していないポインターの使用に関する問題を検出します。

RUN-MEM-NULL

NULL ポインターを使用してメモリにアクセスしない

このルールは、NULL ポインターの使用に関する問題を検出します。

RUN-MEM-RANGE

有効範囲外のポインターを使用してメモリにアクセスしない

このルールは、有効範囲外のバッファーへのアクセス (9 つの要素を持つバッファーの 10 番目の要素へのアクセスなど) に関する問題を検出します。

RUN-MEM-UNINIT

未初期化メモリを読み込まない

このルールは、割り当て済みだが初期化されていないメモリの読み込みに関する問題を検出します。

RUN-MEM-FREEDANG

ダングリング ポインターを解放しない

このルールは、すでに解放済みのメモリ ポインターを解放しようとすることに関する問題を検出します。

RUN-MEM-FREEIL

不正なポインターに対して free を使用しない

このルールは、malloc で割り当てられた有効なメモリ ブロックを指していないポインターを free で解放しようとすることに関する問題を検出します。

RUN-MEM-FREELOC

ローカル メモリ ポインターに対して free を使用しない

このルールは、ローカル メモリ ブロックを指すポインターを free で解放しようとすることに関する問題を検出します。

RUN-MEM-FREEGLOB

グローバル メモリ ポインターに対して free を使用しない

このルールは、グローバル メモリ ブロックを指すポインターを free で解放しようとすることに関する問題を検出します。

RUN-MEM-FREENULL

NULL ポインターに対して free を使用しない

このルールは、NULL ポインターを free で解放しようとすることに関する問題を検出します。

RUN-MEM-MAZERO

サイズに 0 を指定して malloc を使用しない

このルールは、malloc を使用してサイズがゼロのバッファーを割り当てることに関する問題を検出します。

RUN-MEM-CAZEROELEM

要素数に 0 を指定して calloc を使用しない

このルールは、calloc を使用して要素数がゼロのバッファーを割り当てることに関する問題を検出します。

RUN-MEM-CAZEROSIZE

要素サイズに 0 を指定して calloc を使用しない

このルールは、calloc を使用してサイズがゼロの要素を持つバッファーを割り当てることに関する問題を検出します。

RUN-MEM-RAILL

不正なポインターに対して realloc を使用しない

このルールは、malloc で割り当てられた有効なメモリ ブロックを指していないポインターに対してrealloc を使用することに関する問題を検出します。

RUN-MEM-RALOC

ローカル メモリ ポインターに対して realloc を使用しない

このルールは、ローカル メモリ ブロックを指すポインターに対して realloc を使用することに関する問題を検出します。

RUN-MEM-RAGLOB

グローバル メモリ ポインターに対して realloc を使用しない

このルールは、グローバル メモリ ブロックを指すポインターに対して realloc を使用することに関する問題を検出します。

RUN-MEM-RAZERO

新しいサイズに 0 を指定して realloc を使用しない

このルールは、realloc を使用してサイズがゼロのバッファーを割り当てることに関する問題を検出します。

RUN-MEM-LEAK

メモリ リークを避ける

このルールは、メモリ リークを検出します。malloc、 realloc、または calloc で割り当てられたメモリを指すポインターが失われた場合に違反をレポートします。

RUN-MEM-CORRUPT

メモリ破壊を避ける

このルールは、メモリ破壊を検出します。malloc、 realloc、または calloc で割り当てられたメモリ ブロックが、割り当て解除処理中に予期しない方法で上書きされた場合に違反をレポートします。

実行時エラー検出のテスト コンフィギュレーション

C/C++test で利用できるテスト コンフィギュレーションの詳細については、「ビルトイン テスト コンフィギュレーション」を参照してください。

テストの準備がすべて整っているかを検証する場合、[Build Application with...] テスト コンフィギュレーションを使用することを推奨します。 ビルドされるアプリケーションが (たとえば組込みテストのために) 外部で実行されるかどうかを検証するためのテスト コンフィギュレーションもあります。この場合、完全なフローはビルド、デプロイ/実行 (手動)、およびログの参照から構成されます。 

[Build and Run Application with...] テスト コンフィギュレーションは、テスト コンフィギュレーションで指定されたコマンドラインを使ってアプリケーションをビルドして実行する場合に使用します。 

より具体的に言うと、次のようになります。

  • "... Memory Monitoring」 テスト コンフィギュレーションは、テスト対象のアプリケーションに対して実行時エラーを検出します。
  • "... Coverage Monitoring" テスト コンフィギュレーションは、テスト対象のアプリケーションの実行からカバレッジ情報を収集します。
  • - "... Full Monitoring" テスト コンフィギュレーションは、テスト対象のアプリケーションに対して、実行時エラーの検出とカバレッジ情報の収集を行います。

実行時エラー検出の既知の制限事項

  • C スタイルの動的なメモリ割り当て (malloc()、calloc()、realloc() の使用) だけが監視されます。
  • C スタイルの動的なメモリ解放 (free() の使用) だけが監視されます。
  • グローバル配列だけが監視されます (関数で定義される静的配列は監視されません)。
  • メモリ関連の操作を監視するには、テストおよびインストゥルメントされるコンパイル単位で直接メモリ関連の操作を行う必要があります。
  • C++ テンプレートで行われるメモリ関連操作は監視されません。これは結果に影響する可能性があります。
  • 外部ライブラリで行われるメモリ関連操作は監視されません。これは結果に影響する可能性があります。
  • デフォルトでは、メモリ リーク (RUN-MEM-LEAK) はアプリケーション検証モードでのみレポートされます。
  • ベクター データ型の操作は監視されません。
  • No labels