スレッドからエスケープする自動変数またはスレッド ローカル変数
変数が後続スレッドの持続期間を通して有効であることが確認されないままスレッド間で渡される
説明
このチェッカーは、既定の Polyspace® as You Code 解析では非アクティブにされます。Polyspace as You Code 解析で非アクティブにされるチェッカー (Polyspace Access)を参照してください。
この欠陥は、自動またはスレッド ローカル変数が後続スレッドの持続期間を通して有効であることが確認されないままスレッド間でアドレスによって渡された場合に発生します。
欠陥チェッカーは、C11 と POSIX® の両方のスレッドに適用されます。
リスク
自動またはスレッド ローカル変数は、スレッドの開始時点でスタック上に割り当てられ、その存続期間はそのスレッドの最後まで延長されます。この変数は、別のスレッドからアクセスされたときに有効かどうかが保証されません。
たとえば、次の行を使用した C11 スレッドの開始関数を考えてみましょう。
int start_thread(thrd_t *tid) { int aVar = 0; if(thrd_success != thrd_create(tid, start_thread_child, &aVar) { ... } }
関数 thrd_create
は、開始関数 start_thread_child
を使用して子スレッドを作成し、自動変数 aVar
のアドレスをこの関数に渡します。この子スレッドが aVar
にアクセスしたときには、親スレッドが実行を完了しており、aVar
がスタック上に存在しません。このアクセスは予測不能な値の読み取りにつながる可能性があります。
修正方法
スレッド間で変数を渡す場合は、変数の存続期間が両方のスレッドの存続期間以上であることを確認してください。この同期は、次の方法のいずれかで実現できます。
変数
static
を宣言して、現在のスレッドが実行を完了したときにスタックから削除されないようにします。スタックではなくヒープ上に割り当てられ、明示的に割り当て解除する必要があるように、変数用のストレージを動的に割り当てます。両方のスレッドが実行を完了してから割り当て解除が実行されることを確認します。
これらの解決策では、非ローカル メモリで変数を作成する必要があります。代わりに、スレッド全体でローカル変数を安全に共有できる OpenMP のスレッド インターフェイスを使用した shared
キーワードなどの他の解決策も使用できます。
例
結果情報
グループ: 同時実行 |
言語: C | C++ |
既定値: オフ |
コマンド ライン構文: LOCAL_ADDR_ESCAPE_THREAD |
影響度: Medium |
バージョン履歴
R2020a で導入