メインコンテンツ

このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。

スレッド属性の欠落または二重初期化

スレッド属性の初期化が重複しているか、初期化された属性を必要とする関数で使用されるスレッド属性が初期化されていない

説明

この欠陥は、次のいずれかの状態で発生します。

  • pthread_attr_destroy などの関数を中間呼び出しすることなく、pthread_attr_init などの関数でスレッド属性を 2 回初期化する。

    関数 pthread_attr_destroy は、スレッド属性オブジェクトを破棄し、そのオブジェクトに関連付けられたリソースをシステムが再利用できるようにする関数です。

  • 初期化された属性を必要とする pthread_create などの関数において、初期化されていないスレッド属性を使用する。スレッド属性は、過去に 1 度も初期化されていない、関数 pthread_attr_destroy によって破棄されていないなどの理由により、未初期化となる可能性があります。

    初期化されていないスレッド属性は、POSIX® 標準のすべての関数で検出されます。

[結果の詳細] ペインには、その属性が二重に初期化されている、または初期化されていないことが表示されます。また、それまでの関連するイベントも表示されます。

スレッド属性は、pthread_attr_init の呼び出しに成功した場合にのみ、初期化済みであると見なされます。たとえば、スレッド属性は、次の if 分岐では初期化されません。

pthread_attr_t attr;
int thread_success;

thread_success = pthread_attr_init(&attr);
if(thread_success != 0) {
   /* Thread attribute considered noninitialized */
}
この問題は、pthread_attr_init の呼び出しからの戻り値をチェックしない場合にもフラグが付けられます。

リスク

以前に初期化されたスレッド属性を破棄せずにその属性を初期化したり、初期化されていないスレッド属性を使用したりすると、未定義の動作につながります。

修正方法

スレッド属性を使用する前に、関数 pthread_attr_init を使用して属性を初期化します。

pthread_attr_t attr;
int thread_success;

/* Initialize attribute */
thread_success = pthread_attr_init(&attr);
if(thread_success != 0) {
   /* Handle initialization error */
}
...
/* Use attribute */
thread_success = pthread_create(&thr, &attr, &thread_start, NULL);
初期化後は、pthread_attr_destroy を使用してスレッド属性を破棄してから、次の初期化を行います。
pthread_attr_t attr;
int thread_success;

/* Destroy attribute */
thread_success = pthread_attr_destroy(&attr);
if(thread_success != 0) {
   /* Handle destruction error */
}
...
/* Reinitialize attribute */
thread_success = pthread_attr_init(&attr);

すべて展開する

#include <stddef.h>
#include <pthread.h>
#define thread_success 0

extern void *thread_func(void *arg);


int main() {
    pthread_t id;
    pthread_attr_t attr;
    
    if(thread_success == pthread_create(&id, &attr, thread_func, NULL)) {
    }

    return 0;    
}

この例では、属性 attr は、pthread_create 呼び出しでの使用前に初期化されていません。

修正 – スレッド属性は使用前に初期化

関数 pthread_create でスレッド属性を使用する前に、関数 pthread_attr_init で属性を初期化します。

#include <stddef.h>
#include <pthread.h>
#define thread_success 0

extern void *thread_func(void *arg);

int main() {
    pthread_t id;
    pthread_attr_t attr;
    
    if(thread_success != pthread_attr_init(&attr)) {
        return 0;
    }
   
    if(thread_success == pthread_create(&id, &attr, thread_func, NULL)) {
    }
    
    return 0;    
}
#include <stddef.h>
#include <pthread.h>
#define thread_success 0

extern void *thread_func(void *arg);

int main() {
    pthread_t id;
    pthread_attr_t attr;
    
    pthread_attr_init(&attr);
   
    if(thread_success == pthread_create(&id, &attr, thread_func, NULL)) {
    }
    
    return 0;    
}

この例では、pthread_attr_init の戻り値がチェックされていません。スレッド属性の初期化に失敗すると、エラーが処理されません。未定義の可能性のあるスレッド属性は、後に関数 pthread_create で使用されます。

修正 – スレッド属性の初期化によるエラーを処理

1 つの修正方法として、pthread_attr_init からの戻り値が初期化の成功を示す場合にのみスレッド属性を使用するようにします。

#include <stddef.h>
#include <pthread.h>
#define thread_success 0

extern void *thread_func(void *arg);

int main() {
    pthread_t id;
    pthread_attr_t attr;
    
    if(thread_success != pthread_attr_init(&attr)) {
        return 0;
    }
   
    if(thread_success == pthread_create(&id, &attr, thread_func, NULL)) {
    }
    
    return 0;    
}

結果情報

グループ: 同時実行
言語: C
既定値: オフ
コマンド ライン構文: BAD_THREAD_ATTRIBUTE
影響度: Medium

バージョン履歴

R2019b で導入