メインコンテンツ

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

未定義のスレッド ID の使用

スレッド作成に失敗したスレッド ID が後続のスレッド関数で使用された

説明

この欠陥は、pthread_create などのスレッド作成関数が失敗したが、そのスレッド作成からの ID を使い続けた場合に発生します。

たとえば、pthread_join は、前のスレッド作成が失敗した後に未定義のスレッド ID を使用しています。pthread_create からの戻り値が非ゼロであるということは、スレッド作成に失敗したことを示しています。

pthread_t id;
if(0! = pthread_create(&id, attr, start_func, NULL)) {
    ...
    phread_join(id, NULL);
    ...
}
この問題は、pthread_create の呼び出しからの戻り値をチェックしない場合にもフラグが付けられます。

リスク

POSIX® 規格によると、スレッド作成に失敗した場合、スレッド ID の内容は未定義となります。未定義のスレッド ID を使用すると、予期しない結果が生じる可能性があります。

多くの場合、この問題はプログラミング エラーを示しています。たとえば、スレッド作成の成否を判断するために非ゼロ値でテストすることがあります。

if(0 != pthread_create(&id, attr, start_func, NULL))
ゼロの場合は次のとおりです。
if(0 == pthread_create(&id, attr, start_func, NULL))

修正方法

未定義のスレッド ID の使用がプログラミング エラーによるものであれば、そのエラーを修正します。そうでない場合、未定義のスレッド ID を使用しているスレッド関数を削除します。

すべて展開する

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

extern void *thread_func(void *arg);


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

    return 0;
}

この例では、スレッド作成に失敗したことを示す非ゼロ値を pthread_create が返します。*id の値は未定義です。後続の pthread_join の呼び出しでは、この未定義の値を使用しています。

修正 – スレッド作成の成功後にスレッドを結合

1 つの修正方法として、pthread_create がゼロを返す場合のみ、スレッド ID を引数として使用して pthread_join を呼び出します。

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

extern void *thread_func(void *arg);


int main() {
    pthread_t id;
    if(thread_success == pthread_create(&id, NULL, thread_func, NULL)) {
         if(thread_success == pthread_join(id, 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_create(&id, NULL, thread_func, NULL); 
    if(thread_success == pthread_join(id, NULL)) {
    }

    return 0;
}

この例では、pthread_create の戻り値がチェックされていません。スレッド作成に失敗した場合、そのエラーは処理されません。未定義の可能性のあるスレッド ID は、後に関数 pthread_join で使用されます。

修正 – スレッド作成によるエラーを処理

1 つの修正方法として、pthread_create からの戻り値がスレッド作成の成功を示す場合のみ、そのスレッド作成による ID を使用します。

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

extern void *thread_func(void *arg);


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

    return 0;
}

結果情報

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

バージョン履歴

R2019b で導入