Несколько потоков выполняют незащищенные операции с соседними битовыми полями совместно используемой структуры данных
Этот дефект возникает в следующих случаях:
Несколько задач выполняют незащищенные операции с битовыми полями, входящими в одну структуру.
Например, задача работает на поле errorFlag1 и другая задача на местах errorFlag2 в переменной этого типа:
struct errorFlags {
unsigned int errorFlag1 : 1;
unsigned int errorFlag2 : 1;
...
}По меньшей мере одна из незащищенных операций является операцией записи.
Чтобы найти этот дефект, перед анализом необходимо указать параметры многозадачности. Чтобы задать эти параметры, на панели Конфигурация выберите Многозадачность. Дополнительные сведения см. в разделе Настройка многозадачного анализа в многозадачном пространстве вручную.
Смежные битовые поля, которые являются частью одной структуры, могут храниться в одном байте в одной и той же ячейке памяти. Операции чтения или записи для всех переменных, включая битовые поля, выполняются по одному байту или слову одновременно. Чтобы изменить только определенные биты в байте, шаги, подобные этим шагам, выполняются последовательно:
Байт загружается в ОЗУ.
Маска создается таким образом, что только конкретные биты модифицируются до заданного значения, а остальные биты остаются неизменными.
Побитовая операция ИЛИ выполняется между копией байта в ОЗУ и маской.
Байт с определенными измененными битами копируется обратно из ОЗУ.
При обращении к двум различным битовым полям эти четыре шага должны выполняться для каждого битового поля. Если доступ не защищен, все четыре шага для одного битового поля могут не быть выполнены до того, как начнутся четыре шага для другого битового поля. В результате модификация одного битового поля может отменить модификацию соседнего битового поля. Например, в предыдущем примере модификация errorFlag1 и errorFlag2 может происходить в следующей последовательности. Шаги 1,2 и 5 относятся к модификации errorFlag1 и в то время как шаги 3,4 и 6 относятся к шагам errorFlag2.
Байт с обоими errorFlag1 и errorFlag2 немодифицированный копируется в ОЗУ для изменения errorFlag1.
Маска, изменяющая только errorFlag1 побитовый ИЛИ с этой копией.
Байт, содержащий оба errorFlag1 и errorFlag2 немодифицированная копируется в ОЗУ второй раз, для целей модификации errorFlag2.
Маска, изменяющая только errorFlag2 побитовый ИЛИ с этой второй копией.
Версия с errorFlag1 измененное копируется обратно. Эта версия имеет errorFlag2 без изменений.
Версия с errorFlag2 измененное копируется обратно. Эта версия имеет errorFlag1 без изменений и перезаписывает предыдущее изменение.
Чтобы устранить этот дефект, защитите операции с битовыми полями, которые являются частью одной и той же структуры, используя критические разделы, временное исключение или другое средство. См. раздел Защита общих переменных в многозадачном коде.
Чтобы определить существующие защиты, которые можно использовать повторно, см. таблицу и графики, связанные с результатом. В таблице показаны все пары конфликтующих вызовов. В столбце Access Protections отображаются существующие защиты для вызовов. Для просмотра последовательности вызовов функции, приводящей к конфликтам, щелкните
по пиктограмме.
| Группа: Параллелизм |
| Язык: C | C++ |
| По умолчанию: Вкл. |
Синтаксис командной строки:
DATA_RACE_BIT_FIELDS |
| Воздействие: Высокое |
Configure multitasking manually | Critical section details (-critical-section-begin -critical-section-end) | Data race | Data race including atomic operations | Data race through standard library function call | Disabling all interrupts (-routine-disable-interrupts -routine-enable-interrupts) | Find defects (-checkers) | Target processor type (-target) | Tasks (-entry-points) | Temporally exclusive tasks (-temporal-exclusions-file)