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

Вебинар: Использование статических анализаторов кода при разработке безопасного ПО - 19.12

>
>
>
V2609. MISRA. There should be no occurr…
menu mobile close menu
Проверка проектов
Сообщения PVS-Studio
Диагностики общего назначения (General Analysis, C++)
Диагностики общего назначения (General Analysis, C#)
Диагностики общего назначения (General Analysis, Java)
Микрооптимизации (C++)
Диагностика 64-битных ошибок (Viva64, C++)
Реализовано по запросам пользователей (C++)
Cтандарт MISRA
Стандарт AUTOSAR
Стандарт OWASP (C++)
Стандарт OWASP (C#)
Проблемы при работе анализатора кода
Дополнительная информация
toggle menu Оглавление

V2609. MISRA. There should be no occurrence of undefined or critical unspecified behaviour.

27 Авг 2021

Данное диагностическое правило основано на руководстве MISRA (Motor Industry Software Reliability Association) по разработке программного обеспечения.

Это правило актуально только для C. Если в программе возникает неопределённое поведение, то у программиста нет никаких гарантий относительно её исполнения. Такое поведение недопустимо.

Если в программе возникает критическое неуточнённое поведение, это означает, что в зависимости от компилятора и его конфигурации возможно различное исполнение кода. Такое поведение также недопустимо.

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

Однако существует множество ситуаций, которые могут привести к неопределённому или критическому неуточнённому поведению и которые можно распознать алгоритмически. Рассмотрим некоторые из таких случаев.

Часто можно определить потенциальное разыменование нулевого указателя. Рассмотрим следующий фрагмент кода:

void foo()
{
  int len = GetLen();
  char *str = (char *) malloc(mlen + 1);
  str[len] = '\0';
}

При выполнении этого фрагмента кода может произойти разыменование нулевого указателя. Если функция 'malloc' не сможет выделить память, то она запишет 'nullptr' в переменную 'str'. Тогда в выражении 'str[len]' произойдет разыменование 'nullptr', что является неопределенным поведением. Анализатор выдаст следующее предупреждение:

V2609 Undefined behaviour should not occur. There might be dereferencing of a potential null pointer 'str'. Check lines: 4, 5.

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

  • В случае, если переменная 'len' имеет большое значение, выражение 'str[len]' может ссылаться на достаточно удаленные ячейки памяти доступные для записи. Запись туда нуля приведет к непредсказуемым последствиям. Т.е. к тому самому неопределенному поведению.
  • Остановка программы — это тоже критическая ошибка для некоторых приложений.
  • В некоторых микроконтроллерах младшие адреса адресного пространства не защищены от записи, и запись по нулевому указателю никак не будет отловлена операционной системой. Собственно, часто никакой операционной системы и нет.

Более подробно все это рассмотрено в статье "Почему важно проверять, что вернула функция malloc".

Еще одной ситуацией, которую можно распознать алгоритмически, является модификация переменной между двумя точками следования и неоднократное обращение к ней.

Рассмотрим следующий фрагмент кода:

void foo()
{
  int *ptr;
  ....
  *ptr++ = *(ptr + 1);
}

Здесь предполагается, что сначала произойдет увеличение указателя 'ptr' на 1. Затем произойдет вычисление выражения 'ptr + 1', и использоваться будет уже новое значение 'ptr'.

Однако такое предположение программиста неверно. Дело в том, что между двумя точками следования происходит два обращения к переменной 'ptr', одно из которых модифицирует ее значение. В таком случае поведение программы неопределенное.

Анализатор выдаст следующее предупреждение:

V2609 Undefined behaviour should not occur. The 'bufl' variable is modified while being used twice between sequence points.

Также можно определить некорректное использование битовых операторов сдвига. Рассмотрим следующий код:

void foo()
{
  int delta = -2;
  ....
  int expr = DoSomeCalculations();
  expr <<= delta;
}

Здесь переменная 'expr' сдвигается влево на -2 бита. Сдвиг на отрицательное число битов является некорректной операцией и приводит к неопределенному поведению.

Данная диагностика классифицируется как:

  • MISRA-C-1.3
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
Ваше сообщение отправлено.

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


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

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