Несколько потоков выполняют незащищенные операции над смежными битовыми полями структуры разделяемых данных
Этот дефект возникает, когда:
Несколько задач выполняют незащищенные операции над битовыми полями, которые являются частью одной структуры.
Например, задача работает с errorFlag1
поля и другая задача на полевых
errorFlag2
в переменной этого типа:
struct errorFlags { unsigned int errorFlag1 : 1; unsigned int errorFlag2 : 1; ... }
По крайней мере, одна из незащищенных операций является операцией записи.
Чтобы найти этот дефект, перед анализом необходимо задать опции многозадачности. Чтобы задать эти опции, на панели Configuration выберите Multitasking. Для получения дополнительной информации смотрите Настройка многозадачного анализа Polyspace вручную.
Смежные битовые поля, которые являются частью одной и той же структуры, могут храниться в одном байте в том же месте памяти. Операции чтения или записи всех переменных, включая битовые поля, происходят по одному байту или слову за раз. Чтобы изменить только определенные биты в байте, шаги, подобные этим шагам, происходят последовательно:
Байт загружается в ОЗУ.
Маска создается так, что только определенные биты изменяются на целевое значение, а оставшиеся биты остаются неизменными.
Побитовая операция OR выполняется между копией байта в ОЗУ и маской.
Байт с измененными конкретными битами копируется из оперативной памяти.
Когда вы получаете доступ к двум различным битовым полям, эти четыре шага должны быть выполнены для каждого битового поля. Если доступы не защищены, все четыре шага для одного битового поля могут не быть завершены до начала четырех шагов для другого битового поля. В результате модификация одного битового поля может отменить модификацию соседнего битового поля. Например, в предыдущем примере модификация errorFlag1
и errorFlag2
может происходить в следующей последовательности. Шаги 1,2 и 5 относятся к модификации errorFlag1
и в то время как этапы 3,4 и 6 относятся к этапам errorFlag2
.
Байт с обоими errorFlag1
и errorFlag2
немодифицированный копируется в ОЗУ, в целях модификации errorFlag1
.
Маска, которая изменяет только errorFlag1
bitwise OR-ed с этой копией.
Байт, содержащий оба errorFlag1
и errorFlag2
неизмененный копируется в ОЗУ второй раз, в целях изменения errorFlag2
.
Маска, которая изменяет только errorFlag2
bitwise OR-ed с этой второй копией.
Версия с errorFlag1
измененный копируется назад. Эта версия имеет errorFlag2
без изменений.
Версия с errorFlag2
измененный копируется назад. Эта версия имеет errorFlag1
unmodified и перезаписывает предыдущую модификацию.
Чтобы исправить этот дефект, защитите операции для битовых полей, входящих в одну и ту же структуру, с помощью критических разделов, временного исключения или другого средства. См. «Защита общих переменных в многозадачном коде».
Чтобы идентифицировать существующие защиты, которые можно повторно использовать, смотрите таблицу и графики, связанные с результатом. В таблице показаны каждая пара конфликтующих вызовов. В Access Protections столбце показаны существующие средства защиты вызовов. Чтобы увидеть последовательность вызовов функций, ведущую к конфликтам, щелкните значок.
Группа: Параллелизм |
Язык: C | C++ |
По умолчанию: On |
Синтаксис командной строки
: 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)