Мы используем куки, чтобы пользоваться сайтом было удобно.
Хорошо
to the top
close form

Заполните форму в два простых шага ниже:

Ваши контактные данные:

Шаг 1
Поздравляем! У вас есть промокод!

Тип желаемой лицензии:

Шаг 2
Team license
Enterprise license
** Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности
close form
Запросите информацию о ценах
Новая лицензия
Продление лицензии
--Выберите валюту--
USD
EUR
RUB
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Бесплатная лицензия PVS‑Studio для специалистов Microsoft MVP
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Для получения лицензии для вашего открытого
проекта заполните, пожалуйста, эту форму
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
Мне интересно попробовать плагин на:
* Нажимая на кнопку, вы даете согласие на обработку
своих персональных данных. См. Политику конфиденциальности

close form
check circle
Ваше сообщение отправлено.

Мы ответим вам на


Если вы так и не получили ответ, пожалуйста, проверьте, отфильтровано ли письмо в одну из следующих стандартных папок:

  • Промоакции
  • Оповещения
  • Спам

>
>
>
Модельный вариант (ошибки)

Модельный вариант (ошибки)

29 Июл 2024

Некоторые виды программных ошибок невозможно искать статическим анализом "в общем виде", или же это крайне затруднено. В этом случае рационально научиться выявлять множество отдельных паттернов ошибок этого вида. Или, другими словами, искать модельные варианты ошибок. Проще всего будет это понять на примерах.

В языке C и C++ есть ошибки, связанные с наличием в коде неопределённого поведения (Undefined Behavior, UB). Соответственно, статические анализаторы должны выявлять код, приводящий к UB. Вот только это легко сказать, но сложно сделать.

Неопределённое поведение — это не конкретный вид бага или опечатки. В стандартах C и C++ описано большое количество разнообразнейших ситуаций, приводящих к UB. Неопределённому поведению посвящено большое количество статей и книг. Более того, с выходом новых стандартов языков C и C++, появляются новые языковые конструкции, неверное использование которых приводит к неопределённому поведению новыми способами.

Поэтому на практике выявление неопределённого поведения сводится к созданию множества отдельных диагностик, каждая из которых ищет свои паттерны (модельные варианты) ошибок. Например:

  • аргументом оператора delete является указатель типа void * (V772);
  • объявлен макрос, имя которого перекрывает ключевое слово или зарезервированный стандартом идентификатор (V1059);
  • некорректные операции сдвига (V610);
  • и так далее.

Рассмотрим ещё один пример — разыменование нулевого указателя. Кстати, это тоже частный случай неопределённого поведения, но все рассматривают этот тип ошибок отдельно.

Анализатор может находить множество таких ошибок, выполняя анализ потока данных и управления. Простейший, но при этом реальный пример:

ViewProviderPage* vpp = getViewProviderPage(dView);
if (!vpp) {
  return vpp->getQGVPage();

PVS-Studio предупреждает (V522), что если мы войдём внутрь оператора if, то произойдёт разыменование нулевого указателя.

К сожалению, в силу вычислительной сложности статические анализаторы не могут в общем случае отследить все пути выполнения программы и передачи данных. Поэтому анализаторы часто не знают, может указатель являться нулевым или нет.

Предупреждать на всякий случай об использовании всех указателей, про которые нет информации — плохая идея. Появится слишком много ложных срабатываний и анализатор невозможно будет использовать. Полезные срабатывания потонут в бесконечном потоке бесполезных, и программист перестанет их просматривать. Поэтому в PVS-Studio мы придерживаемся определённой философии: предупреждать только в том случае, когда есть повод подозревать наличие ошибки.

Можно ли что-то сделать, если даже анализатор не смог вычислить, может указатель быть нулевым или нет? Да, можно. Например, в PVS-Studio реализован вот такой модельный вариант поиска ошибок:

Ms::Segment* startSegment = score()->selection().startSegment();

startSegment->measure()->firstEnabled();  // <= (1)

if (!startSegment) {                      // <= (2)
  return nullptr;
}

Предположим, анализатор в этом случае не смог вычислить, может ли указатель startSegment быть нулевым или нет. Однако косвенно можно с большой долей достоверности утверждать, что код всё-таки содержит ошибку.

Обратите внимание, указатель в начале разыменовывается (1), а затем проверяется (2). Раз указатель проверяют, значит он может быть равен nullptr. Следовательно, выше может произойти разыменование нулевого указателя.

Анализатор PVS-Studio распознаёт такой ошибочный паттерн и выдаёт предупреждение V595. Кстати, это очень распространённый антипаттерн, и мы уже собрали большую коллекцию таких багов.

Это очень показательный пример. Теоретически найти использование всех нулевых указателей можно с помощью анализа потока данных. Однако на практике анализаторы упираются в вычислительную сложность этой задачи. На помощь приходит поиск модельных вариантов ошибок, один из которых мы только что рассмотрели. Есть и другие способы, например, диагностика V757. Дополняя другу друга, диагностики хорошо справляются с общей задачей поиска нулевых указателей.

ГОСТ Р 71207-2024 — Статический анализ программного обеспечения. В разделе терминов дано следующее определение модельного варианта (ошибки):

Подтип некоторого типа ошибки в программе, отнесение к которому осуществляется исходя из особенностей реализации ошибки данного типа и особенностей языка программирования.

Примечание — Разбиение типа ошибки на модельные варианты применяется из-за технологических ограничений статического анализа в целях эффективной работы статических анализаторов, сводя задачу поиска ошибки более общего типа к задаче поиска ошибок множества подтипов.

Дополнительные ссылки:

Популярные статьи по теме


Комментарии (0)

Следующие комментарии next comments
close comment form