このページの内容は最新ではありません。最新版の英語を参照するには、ここをクリックします。
隣接するビット フィールドでのデータ レース
複数のスレッドが共有されたデータ構造体の隣接するビット フィールドで非保護操作を実行
説明
このチェッカーは、既定の Polyspace® as You Code 解析では非アクティブにされます。Polyspace as You Code 解析で非アクティブにされるチェッカー (Polyspace Access)を参照してください。
この欠陥は、以下の場合に発生します。
複数のタスクが、同じ構造体の一部であるビット フィールドに対して非保護操作を実行した。
たとえば、次の型の変数で、あるタスクがフィールド
errorFlag1
を操作し、別のタスクがフィールドerrorFlag2
を操作した場合です。操作は相互にアトミックではないと仮定します。つまり、ある操作が完了してから次の操作が開始されるようにするための保護メカニズムが実装されていません。struct errorFlags { unsigned int errorFlag1 : 1; unsigned int errorFlag2 : 1; ... }
非保護操作のうち少なくとも 1 は書き込み操作である。
この欠陥を検出するには、解析前にマルチタスキング オプションを指定します。[構成] ペインで [マルチタスキング] を選択してこれらのオプションを指定します。詳細は、Polyspace マルチタスキング解析の手動設定を参照してください。
リスク
同じ構造体の一部である隣接するビット フィールドは、同じメモリ位置にある 1 バイトに保存される可能性があります。ビット フィールドを含むすべての変数に対する読み取り操作または書き込み操作は、一度に 1 バイトまたは 1 ワードで発生します。1 つのバイト内の特定のビットのみを変更するには、次のようなステップが順番に発生します。
そのバイトが RAM に読み込まれます。
特定のビットだけが意図された値に変更され、残りのビットは変更されないようにマスクが作成されます。
RAM 内のバイトのコピーとマスク間でビット OR 演算が実行されます。
特定のビットが変更されたバイトが RAM からコピーされます。
2 つの異なるビット フィールドにアクセスする場合は、各ビット フィールドに対してこの 4 つのステップを実行する必要があります。アクセスが保護されていない場合は、1 つのビット フィールドに対する 4 つすべてのステップが完了しなくても、他のビット フィールドに対する 4 つのステップが開始される可能性があります。その結果、1 つのビット フィールドの変更によって、隣接するビット フィールドの変更が取り消される可能性があります。たとえば、前述の例では、errorFlag1
と errorFlag2
の変更を次の順序で行うことができます。ステップ 1、2、および 5 は errorFlag1
の変更に関連しますが、ステップ 3、4、および 6 は errorFlag2
の変更に関連します。
変更されていない
errorFlag1
とerrorFlag2
の両方を含むバイトがerrorFlag1
を変更する目的で RAM にコピーされます。errorFlag1
だけを変更するマスクがこのコピーとビット単位 OR されます。errorFlag2
を変更する目的で、変更されていないerrorFlag1
とerrorFlag2
の両方を含むバイトが 2 回 RAM にコピーされます。errorFlag2
だけを変更するマスクがこの 2 つ目のコピーとビット単位 OR されます。errorFlag1
が変更されたバージョンがコピーされます。このバージョンのerrorFlag2
は変更されていません。errorFlag2
が変更されたバージョンがコピーされます。このバージョンのerrorFlag1
は変更されておらず、以前の変更が上書きされます。
修正方法
この欠陥を修正するには、クリティカル セクション、時間的排他、または別の手段を使用することによって同じ構造体の一部であるビット フィールドに対する操作を保護します。マルチタスキング コードでの共有変数の保護を参照してください。
再利用できる既存の保護を特定するには、結果に関連付けられている表とグラフを確認します。表では競合する呼び出しの各ペアが示されます。[アクセス保護] 列には、その呼び出しについての既存の保護が表示されます。競合につながる関数呼び出しの順序を確認するには、 アイコンをクリックします。
例
結果情報
グループ: 同時実行 |
言語: C | C++ |
既定値: オン |
コマンド ライン構文: DATA_RACE_BIT_FIELDS |
影響度: High |
バージョン履歴
R2020b で導入
参考
データ レース
| すべての割り込みを無効にする (-routine-disable-interrupts -routine-enable-interrupts)
| 時間的に排他なタスク (-temporal-exclusions-file)
| クリティカル セクション詳細 (-critical-section-begin -critical-section-end)
| タスク (-entry-points)
| マルチタスクを手動で構成
| ターゲット プロセッサ タイプ (-target)
| 欠陥の検出 (-checkers)
| 標準ライブラリ関数呼び出しでデータ レースが発生しました
トピック
- Polyspace でのマルチタスキング プログラムの解析
- マルチタスキング コードでの共有変数の保護
- Polyspace デスクトップ ユーザー インターフェイスでの Bug Finder の結果の解釈
- Polyspace Access Web インターフェイスでの Bug Finder の結果の解釈 (Polyspace Access)
- Polyspace ユーザー インターフェイスでのバグ修正または正当化による結果への対処
- Polyspace Access でのバグ修正または正当化による結果への対処 (Polyspace Access)
- マルチタスキング コードでのアトミック操作の定義
- サポートされていないマルチスレッド環境への同時実行欠陥チェッカーの拡張