Как написать тесты, которые проверяют условия гонки?
В настоящее время я работаю над большим проектом, который недавно претерпел много изменений, в первую очередь добавление поддержки потоковой передачи.
Проходя через код, я определил разделы, которые потенциально могут вызвать условия гонки, если не сейчас, то когда-нибудь в будущем. Чтобы предотвратить такую регрессию, я хотел бы написать тест, который может надежно обнаружить состояние расы в этом конкретном регионе, чтобы гарантировать, что никакие будущие коммиты не вызовут эту ошибку.
То код не завален операторами sleep (), но является потенциальным тупиком и минным полем гонки, и я хочу обеспечить надежность.
Этот проект полностью написан на языке C. Итак, есть ли у меня возможность писать модульные тесты для предотвращения условий гонки?
3 ответа:
Условия расы по своей сути являются результатом недетерминизма. Если вы не можете гарантировать, что вызывающая последовательность безопасна, то введите ряд проверок во время выполнения, которые проверяют соблюдение инвариантов протокола. Тогда, по крайней мере, у вас будет доказательство ошибки, когда бы она ни произошла.
Хотя это не решит вашу проблему, это, по крайней мере, даст вам инструмент для количественной оценки степени проблемы.
Если какая-либо из гонок вызвана событиями, выходящими за рамки приложения, тогда любой статический анализ потребовал бы, чтобы это также было смоделировано, чтобы иметь возможность обнаружить условия.
Инструмент Valgrind DRD может использоваться для обнаружения многих ошибок потока. Просто используйте этот инструмент и запустите свои обычные тестовые случаи.
Clang Thread Sanitizer работает, наблюдая за процессом тестирования во время его выполнения. Всякий раз, когда поток считывает или записывает незащищенную память, он записывает ее и сообщает вам, если какой-либо фрагмент памяти был получен незащищенным несколькими потоками.