メインコンテンツ

AUTOSAR C++14 Rule A15-3-3

Main function and a task main function shall catch at least: base class exceptions from all third-party libraries used, std::exception and all otherwise unhandled exceptions

説明

ルール定義

Main function and a task main function shall catch at least: base class exceptions from all third-party libraries used, std::exception and all otherwise unhandled exceptions.

根拠

main() またはタスク main 関数の実行中は、複数の例外が発生する可能性があります。次に例を示します。

  • クラス std::exception の明示的に発生した例外

  • 使用されているサードパーティ ライブラリから発生した例外

  • 予期せぬ例外

これらの例外のいずれもハンドラーと一致しなかった場合は、コンパイラが関数 std::terminate() を暗黙的に呼び出して、プログラム実行を異常終了させます。使用しているハードウェアとソフトウェアによっては、この終了プロセスによって std::abort() が呼び出され、スタック内の変数を削除せずにプログラム実行が中止される場合があります。このような異常終了はメモリ リークやセキュリティの脆弱性につながります。

未処理例外は、プログラム実行の異常終了を引き起こし、メモリ リークやセキュリティの脆弱性につながる可能性があります。これらの問題を回避するには、main() またはタスク main 関数の処理を try-catch ブロック内で実行します。catch ブロックで以下を行います。

  • std::exception 型の例外を該当する catch ブロックで明示的に処理する。

  • サードパーティ ライブラリから発生する例外の基底クラスを処理する。

  • 予期せぬ例外を catch(...) ブロックで処理する。

Polyspace 実装

  • 以下の場合に、Polyspace® は関数 main() またはタスク main 関数にフラグを設定します。

    • 関数内で未処理例外が発生した。たとえば、try-catch ブロックの外側または catch ブロック内で発生した例外は未処理のままの可能性があります。

    • 関数に try-catch ブロックが存在しない。

    • 関数に std::exception 型の例外を明示的に処理する catch ブロックが存在しない。

    • 関数に未処理例外を処理する catch-all ブロックまたは catch(...) ブロックが存在しない。

  • Polyspace は、サードパーティ ライブラリからの例外が処理されるかどうかをチェックしません。

  • Polyspace は、未処理例外が発生しない可能性があっても、関数 main() またはタスク main 関数にフラグを設定します。

Polyspace は関数 main() を検出します。関数をタスク main 関数として指定するには、以下のコンパイル オプションを使用します。

  • -entry-points <name>

  • -cyclic-tasks <name>

  • -interrupts <name>

トラブルシューティング

ルール違反が想定されるものの、Polyspace から報告されない場合は、コーディング規約違反が想定どおりに表示されない理由の診断を参照してください。

すべて展開する

この例では、Polyspace が、すべての例外を処理しない main() とタスク main 関数にどのようにフラグを設定するかを示します。関数の NoncompliantNoncompliant2、および Compliant2 をタスク main 関数として指定するには、コンパイル オプション -entry-points Noncompliant,Noncompliant2,Compliant を使用します。


#include <stdexcept>
void f_throw() {             // Compliant
  throw 1;
}
void Noncompliant()     // Noncompliant 
{
  try {

  } catch (std::exception& e) {
	  f_throw();              // throw
  } catch (...) {
	  throw;
  }
}
int Noncompliant2()     // Noncompliant 
{
  f_throw();              // throw
  try {

  } catch (std::exception& e) {
  } catch (...) {
  }
  return 0;
}
int Compliant()   // Compliant
{

  try {
    // program code
  } catch (std::runtime_error& e) {
    // Handle runtime errors
  } catch (std::logic_error& e) {
    // Handle logic errors
  } catch (std::exception& e) {
    // Handle all expected exceptions
  }catch (...) {
    // Handle all unexpected exceptions
  }

  return 0;
}
int main()   // Noncompliant
{

  try {
    // program code
  } catch (std::runtime_error& e) {
    // Handle runtime errors
  } catch (std::logic_error& e) {
    // Handle logic errors
  } catch (std::exception& e) {
    // Handle all expected exceptions
  }
  return 0;
}

  • 関数 f_throw() は未処理例外で終了します。この関数は main 関数でもタスク main 関数でもないため、Polyspace はこの関数にフラグを設定しません。

  • 関数の Noncompliant()Noncompliant2() はタスク main 関数として指定されています。これらの関数では、f_throw が処理されない例外を発生させます。これらのタスク main 関数は発生する可能性のあるすべての例外を処理しないため、Polyspace はこれらの関数にフラグを設定します。例外を発生させる可能性のある処理を try-catch ブロックに入れて、発生する可能性のある例外を処理します。

  • 関数 main() には、未処理例外を処理するための catch(...) ブロックがありません。関数 main() は発生する可能性のあるすべての例外を処理しないため、Polyspace はこの関数にフラグを設定します。

  • 関数 Compliant はタスク main 関数として指定されています。この関数には、発生する可能性のあるすべての例外用の catch があります。Polyspace はこの関数にフラグを設定しません。

チェック情報

グループ: Exception handling
カテゴリ: Required、Partially automated

バージョン履歴

R2020b で導入