ロック解除が重複しています
ロック関数はタスク中 2 回呼び出されますが、間にロック解除関数の呼び出しはありません。
説明
このチェッカーは、既定の Polyspace® as You Code 解析では非アクティブにされます。Polyspace as You Code 解析で非アクティブにされるチェッカー (Polyspace Access)を参照してください。
この欠陥は、以下の場合に発生します。
タスクはロック関数
my_lockを呼び出します。タスクは対応するロック解除関数
my_unlockを呼び出します。タスクは再度
my_unlockを呼び出します。タスクはmy_unlockの2 回の呼び出しの間でmy_lockを 2 回目は呼び出しません。
マルチタスキング コードでは、ロック関数はコードのクリティカル セクションを開始し、ロック解除関数はそれを終了させます。タスク task1 がロック関数 my_lock を呼び出すとき、my_lock を呼び出し中の他のタスクは task1 が対応するロック解除関数を呼び出すまで待たなくてはなりません。
この欠陥を検出するには、次のいずれかのメソッドを使用してロック関数とロック解除関数を指定します。
Polyspace Bug Finder™ で自動的に検出できるいずれかの同時実行プリミティブ型を呼び出します。Polyspace でのスレッド作成とクリティカル セクションの自動検出を参照してください。
ロック関数およびロック解除関数は、解析前に構成オプションとして明示的に指定します。Polyspace ではロック関数およびロック解除関数の両方が
void func(void)形式に準拠しなくてはなりません。クリティカル セクション詳細 (-critical-section-begin -critical-section-end)を参照してください。
リスク
ロック解除の重複の欠陥は、コーディング エラーを示す可能性があります。別のクリティカル セクションを終了するために異なるロック解除関数を呼び出す必要があった可能性もあります。最初のロック解除関数を途中で呼び出しているが、2 番目の呼び出しだけがクリティカル セクションの終了を意図していた可能性もあります。
修正方法
修正方法は欠陥の根本原因によって異なります。
コードの各クリティカル セクション、つまり、Atomic ブロックとして実行するセクションを特定します。セクションの最初でロック関数を呼び出します。セクションの最後でのみ、ロック関数に対応するロック解除関数を呼び出します。ロック解除関数のそれ以外の冗長な呼び出しはすべて削除します。
以下の修正例を参照してください。この問題を回避するには、同じモジュール内のロック関数とロック解除関数を同じ抽象化レベルで呼び出す手法に従うことをお勧めします。次の例の場合、func はロック関数とロック解除関数を同じレベルで呼び出していますが、func2 はそうではありません。
void func() {
my_lock();
{
...
}
my_unlock();
}
void func2() {
{
my_lock();
...
}
my_unlock();
}問題を修正しない場合は、改めてレビューされないように結果またはコードにコメントを追加します。詳細は、以下を参照してください。
Polyspace ユーザー インターフェイスでのバグ修正または正当化による結果への対処 (Polyspace ユーザー インターフェイスで結果をレビューする場合)。
Polyspace Access でのバグ修正または正当化による結果への対処 (Polyspace Access) (Web ブラウザーで結果をレビューする場合)。
コードへの注釈付けと既知の結果または許容可能な結果の非表示 (IDE で結果をレビューする場合)
チェッカーの拡張
Polyspace でサポートされていないロック解除関数を使用する場合があります。その場合、ロック解除関数を、POSIX® の既知の同等の関数にマッピングすることで、このチェッカーを拡張します。サポートされていないマルチスレッド環境への同時実行欠陥チェッカーの拡張を参照してください。
例
結果情報
| グループ: 同時実行 |
| 言語: C | C++ |
| 既定値: オン |
コマンド ライン構文: DOUBLE_UNLOCK |
| 影響度: High |
