EN JP CN

CONC.NO_UNLOCK

CONC.NO_UNLOCK

ロック解除の欠落

CONC.NO_UNLOCK チェッカーは、対応するロック解除がないロックされたスレッドにより、可能性のあるデッドロックをレポートします。

脆弱性とリスク

ロックの解放を忘れるとデッドロックになる場合があります。ロックが維持されたまま解放されない場合、そのロックが解放されるまで、それ以降のロック獲得の呼び出しは進みません。

軽減と防止

ロック競合を回避するための指針:

  • コードのロックされるセクションを、できるだけ小さく、できるだけ単純にして、理解しやすいようにします。
  • データ競合のような同時実行問題を起こす可能性のあるコードのセクションをロックしないこと。
  • 循環待ち条件は、是が非でも避けること。
  • いくつかのロックを、通常はエスカレートしたガードパターンで使用する場合、環境ごとに厳密に同じエスカレーションが実行されることを必ず確認する。

脆弱コード例

1  #include <pthread.h>
2  
3  extern int z();
4  
5  void foo(pthread_mutex_t *mutex) {
6    pthread_mutex_lock(mutex);
7    switch (z()) {
8      case 0:
9        return;
10     case 1:
11       break;
12   }
13   pthread_mutex_unlock(mutex);
14 }

Klocwork case 0 が有効な場合に、6 行目で mutex がロックされ 9 行目でロック解除されていないことをレポートします。

修正コード例

1  #include <pthread.h>
2  
3  extern int z();
4  
5  void foo(pthread_mutex_t *mutex) {
6    pthread_mutex_lock(mutex);
7    switch (z()) {
8      case 0:
9        pthread_mutex_unlock(mutex);
10        return;
11     case 1:
12       break;
13   }
14   pthread_mutex_unlock(mutex);
15 }

修正バージョンでは、ロック解除が 9 行目に含まれています。

関連チェッカー

拡張機能

このチェッカーは機能を拡張できます。関連するナレッジベースレコードには以下の種類があります。

詳細については、C/C++ 解析のチューニングを参照してください。