CONC.NO_LOCK

欠落しているロック

CONC.NO_LOCK チェッカーは、ロック解除呼び出しに対応するロックがない場合にフラグを立てます。

脆弱性とリスク

特定のスレッドでロックされていないときに、コードが変数またはミューテックスをロック解除しようとすると、予期しない動作が発生する可能性があります。

軽減と防止

特定のスレッドによってロックされていない限り、リソースをロック解除しないでください。

脆弱コード例

コピー
  #include <pthread.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <unistd.h>
 
  pthread_t tid[2];
 
  void *trythis(void *arg)
 {
     pthread_mutex_t lock;
     if (pthread_mutex_init(&lock, NULL) != 0) {
         printf("\n mutex init has failed\n");
         return NULL;
     }

     pthread_mutex_unlock(&lock);

     return NULL;
 }

 int main(void)
 {
     int i = 0;
     int error;

     error = pthread_create(&(tid[i]),
                            NULL,
                            &trythis, NULL);
     if (error != 0)
         printf("\nThread can't be created :[%s]",
                strerror(error));

     pthread_join(tid[0], NULL);

     return 0;
 }

この準拠していない例では、コードはまだロックされていないミューテックスをロック解除しようとしているため、Klocwork は 27 行目で CONC.NO_LOCK 欠陥を報告します。

修正コード例

コピー
  #include <pthread.h>
  #include <stdio.h>
  #include <stdlib.h>
  #include <string.h>
  #include <unistd.h>
 
  pthread_t tid[2];
 
  void *trythis(void *arg)
 {
     pthread_mutex_t lock;
     if (pthread_mutex_init(&lock, NULL) != 0) {
         printf("\n mutex init has failed\n");
         return NULL;
     }

     pthread_mutex_lock(&lock);
     pthread_mutex_unlock(&lock);

     return NULL;
 }

 int main(void)
 {
     int i = 0;
     int error;

     error = pthread_create(&(tid[i]),
                            NULL,
                            &trythis, NULL);
     if (error != 0)
         printf("\nThread can't be created :[%s]",
                strerror(error));

     pthread_join(tid[0], NULL);

     return 0;
 }

修正された例では、コードは特定のスレッドに沿ってロックされたミューテックスを適切にロック解除しています。

拡張機能

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

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