Неточное отображение функции на стандартную функцию для точного анализа
-code-behavior-specifications file
-code-behavior-specifications позволяет связать определенное поведение с элементами кода и изменить результаты проверок этих элементов. Здесь, file - это XML-файл, который назначает определенные варианты поведения элементам кода, таким как функции.file
Например, можно:
Сопоставьте функции библиотеки с соответствующими стандартными функциями, которые распознает Polyspace ®. Сопоставление со стандартными библиотечными функциями может помочь в повышении точности или автоматическом обнаружении новых потоков.
Укажите, что функция имеет особое поведение или должна подвергаться специальным проверкам.
Например, можно указать, что функция должна принимать только адреса инициализированных переменных в качестве аргументов, или что функция не должна использоваться полностью.
При выполнении проверки из командной строки укажите абсолютный путь к XML-файлам или путь относительно папки, из которой выполняется команда. Если проверка выполняется из пользовательского интерфейса (только для настольных продуктов), укажите параметр вместе с абсолютным путем к XML-файлу в поле Другое. Посмотрите Other. Обратите внимание, что отчет, созданный на основе результатов анализа, показывает только использование этого параметра, а не сведения о том, какое поведение было связано с элементами кода.
Образец файла шаблона code-behavior-specifications-template.xml показывает синтаксис XML. Файл находится в где polyspaceroot\polyspace\verifier\cxx\ является папкой установки Polyspace. polyspaceroot
Если в качестве расширений кода в IDE используется Polyspace, введите эту опцию в файл опций анализа. См. файл параметров.
Синтаксис XML: <function name="custom_function" std="std_function"> </function>
Используйте эту запись в XML-файле, чтобы уменьшить количество проверок оранжевого цвета из неточного анализа программы поиска кода (или ложных негативов из неточного анализа программы поиска ошибок). Иногда проверка не анализирует определенные виды функций именно из-за внутренних ограничений статической проверки. В этих случаях, если вы находите стандартную функцию, которая является близким аналогом вашей функции, используйте это отображение. Хотя сама функция не анализируется, анализ более точен в местах, где вы называете функцию. Например, если проверка не может проанализировать вашу функцию cos32 точно и учитывает полный диапазон для его возвращаемого значения, сопоставьте его с cos функция для возвращаемого значения в [-1,1].
Проверка игнорирует тело вашей функции. Однако проверка эмулирует поведение функции следующими способами:
Проверка предполагает те же возвращаемые значения для функции, что и стандартная функция.
Например, при отображении функции cos32 в стандартную функцию cos, проверка предполагает, что cos32 возвращает значения в [-1,1].
Проверка выполняется для тех же проблем, что и проверка со стандартной функцией.
Например, при отображении функции acos32 в стандартную функцию acos, Invalid use of standard library routine check определяет, является ли аргумент acos32 в [-1,1].
Функции, которые можно сопоставить, включают в себя:
Стандартные библиотечные функции из math.h.
Функции управления памятью из string.h.
__ps_meminit: Функция Polyspace, инициализирующая область памяти.
Иногда проверка не распознает функцию инициализации памяти и выдает оранжевый Non-initialized local variable проверьте переменную, инициализированную с помощью этой функции. Если известно, что функция инициализации памяти инициализирует переменную по ее адресу, сопоставьте функцию с __ps_meminit. Чек становится зеленым.
__ps_lookup_table_clip: Функция Polyspace, возвращающая значение в диапазоне входного массива.
Иногда проверка учитывает полный диапазон для возвращаемых значений функций, которые просматривают значения в больших массивах (функции таблицы поиска). Если известно, что возвращаемое значение функции таблицы поиска должно находиться в диапазоне значений в ее входном массиве, сопоставьте функцию с __ps_lookup_table_clip.
В коде, сгенерированном из моделей, проверка по умолчанию делает это предположение для функций таблицы поиска. Чтобы определить, использует ли таблица поиска линейную интерполяцию и нет ли экстраполяции, проверка использует имена функций. Отображение используется только для рукописных функций, например, функций в блоке C/C + + S-функции (Simulink). Названия этих функций не соответствуют определенным соглашениям. Необходимо явно указать их.
См. также раздел Распространение средств поиска ошибок для стандартных библиотечных функций на пользовательские библиотеки.
Синтаксис XML: <function name="custom_function" std="std_function"> </function>
Используйте эту запись в XML-файле для автоматического обнаружения функций создания потоков и функций, начинающих и завершающих критические разделы. Polyspace поддерживает автоматическое обнаружение только для некоторых семейств многозадачных примитивов. Расширение поддержки с помощью этой XML-записи.
Если функция создания потоков, например, не принадлежит одному из поддерживаемых семейств, сопоставьте ее с поддерживаемым примитивом параллелизма.
См. раздел Распространение проверки дефектов параллелизма на неподдерживаемые многопоточные среды.
Этот раздел применим только к анализу Bug Finder.
Синтаксис XML:
<function name="function_name"> <behavior name="FORBIDDEN_FUNC"> </function>
Используйте эту запись в XML-файле, чтобы указать, не должна ли функция использоваться в исходном коде.
См. раздел Пометка устаревших или небезопасных функций с помощью средств поиска ошибок.
Синтаксис XML:
<function name="function_name"> <check name="ARGUMENT_POINTS_TO_INITIALIZED_VALUE" arg="n"/> </function>
n указывает, какой аргумент должен быть проверен для инициализации буфера.Используйте эту запись в XML-файле, чтобы указать, должен ли аргумент указателя на функцию указывать на инициализированный буфер.
Смотрите.
Синтаксис XML:
<global_scope>
<parameter name="MAX_NUMBER_NESTED_LEVEL_CONTROL_FLOW" value="n1"/>
<parameter name="MAX_NUMBER_NESTED_LEVEL_INCLUDES" value="n2"/>
<parameter name="MAX_NUMBER_CONSTANT_IN_ENUMERATION" value="n3"/>
<parameter name="MAX_NUMBER_MACROS_TRANSLATION_UNIT" value="n4"/>
<parameter name="MAX_NUMBER_MEMBERS_IN_STRUCT" value="n5"/>
<parameter name="MAX_NUMBER_NESTED_MEMBERS_IN_STRUCT" value="n6"/>
<parameter name="NUMBER_SIGNIFICANT_CHARACTER_EXTERNAL_IDENTIFIER" value="n7"/>
<parameter name="NUMBER_SIGNIFICANT_CHARACTER_INTERNAL_IDENTIFIER" value="n8"/>
</global_scope>n1,..,n8 задает числовые значения.Использовать записи для следующих параметров, чтобы указать ограничения на некоторые аспекты программы. Изменения влияют на проверку n1,..,n6MISRA C:2012 Rule 1.1.
MAX_NUMBER_NESTED_LEVEL_CONTROL_FLOW: Максимальная глубина вложенности, допустимая в операторах потока управления.
MAX_NUMBER_NESTED_LEVEL_INCLUDES: Максимальный уровень включения, разрешенный при использовании файлов включения.
MAX_NUMBER_CONSTANT_IN_ENUMERATION: Максимально допустимое количество констант в перечислении.
MAX_NUMBER_MACROS_TRANSLATION_UNITМаксимальное количество макросов, разрешенное в блоке преобразования.
MAX_NUMBER_MEMBERS_IN_STRUCTМаксимальное число членов в структуре.
MAX_NUMBER_NESTED_MEMBERS_IN_STRUCT: Максимально допустимые уровни вложенности в структуре.
Использовать записи и n7 чтобы указать, сколько символов должно сравниваться, чтобы определить, являются ли два идентификатора идентичными. Изменения влияют на проверку правил 5.x.n8
NUMBER_SIGNIFICANT_CHARACTER_EXTERNAL_IDENTIFIER: Количество символов для сравнения внешних идентификаторов. Внешние идентификаторы объявлены с глобальной областью или классом хранения extern.
NUMBER_SIGNIFICANT_CHARACTER_INTERNAL_IDENTIFIER: Количество символов для сравнения внутренних идентификаторов.
Примеры в следующих разделах относятся к анализу проверки кода. Примеры поиска ошибок см. в:
Можно адаптировать XML-файл сопоставления образцов, поставляемый при установке Polyspace, и сопоставить функцию со стандартной функцией.
Предположим, что при проверке по умолчанию появляется оранжевый User assertion проверьте этот код:
double x = acos32(1.0) ;
assert(x <= 2.0);acos32 ведет себя как функция acos и возвращаемое значение равно 0. Вы ожидаете проверку на assert оператор должен быть зеленым. Однако проверка считает, что acos32 возвращает любое значение в диапазоне типов double потому что acos32 точно не анализируется. Чек оранжевый. Для отображения функции acos32 кому acos:
Копировать файл code-behavior-specifications-template.xml от в другое место, например, polyspaceroot\polyspace\verifier\cxx\"C:\Polyspace_projects\Common\Config_files". Измените разрешения на запись в файл.
Чтобы преобразовать функцию в стандартную, измените содержимое XML-файла. Для отображения функции acos32 в стандартную библиотечную функцию acos, измените следующий код:
<function name="my_lib_cos" std="acos"> </function>
<function name="acos32" std="acos"> </function>
Укажите расположение файла для проверки:
Проверка кода:
polyspace-code-prover -code-behavior-specifications "C:\Polyspace_projects\Common\Config_files\code-behavior-specifications-template.xml"
Сервер проверки кода:
polyspace-code-prover-server -code-behavior-specifications "C:\Polyspace_projects\Common\Config_files\code-behavior-specifications-template.xml"
Иногда аргументы функции не сопоставляются один к одному с аргументами стандартной функции. В этих случаях перенастройте аргумент функции на аргумент стандартной функции. Например:
__ps_lookup_table_clip:
Эта функция, относящаяся к Polyspace, принимает в качестве аргумента только массив таблицы подстановки и возвращает значения в диапазоне таблицы подстановки. Функция таблицы подстановки может иметь дополнительные аргументы, помимо самого массива таблицы подстановки. В этом случае используйте переопределение аргументов, чтобы указать, какой аргумент функции является массивом таблицы подстановки.
Например, предположим, что функция my_lookup_table имеет следующее объявление:
double my_lookup_table(double u0, const real_T *table,
const double *bp0);my_lookup_table является массивом таблицы поиска. В файле code-behavior-specifications-template.xml, добавьте следующий код:<function name="my_lookup_table" std="__ps_lookup_table_clip">
<mapping std_arg="1" arg="2"></mapping>
</function>При вызове функции:
res = my_lookup_table(u, table10, bp);
res =__ps_lookup_table_clip(table10);
res находится в диапазоне значений в table10.__ps_meminit:
Эта функция, специфичная для Polyspace, принимает адрес памяти в качестве первого аргумента и число байт в качестве второго аргумента. Функция предполагает, что байты в памяти, начиная с адреса памяти, инициализируются с допустимым значением. Функция инициализации памяти может иметь дополнительные аргументы. В этом случае используйте переопределение аргумента, чтобы указать, какой аргумент функции является начальным адресом, а какой - числом байт.
Например, предположим, что функция my_meminit имеет следующее объявление:
void my_meminit(enum InitKind k, void* dest, int is_aligned, unsigned int size);
code-behavior-specifications-template.xml, добавьте следующий код:<function name="my_meminit" std="__ps_meminit">
<mapping std_arg="1" arg="2"></mapping>
<mapping std_arg="2" arg="4"></mapping>
</function>При вызове функции:
my_meminit(INIT_START_BY_END, &buffer, 0, sizeof(buffer));
__ps_meminit(&buffer, sizeof(buffer));
sizeof(buffer) количество байтов, начиная с &buffer инициализированы.memset: Переменное число аргументов.
Если функция имеет переменное количество аргументов, ее нельзя сопоставить непосредственно стандартной функции без явного переопределения аргументов. Например, скажем, ваша функция объявлена как:
void* my_memset(void*, int, size_t, ...)
memset используйте следующее сопоставление:<function name="my_memset" std="memset">
<mapping std_arg="1" arg="1"></mapping>
<mapping std_arg="2" arg="2"></mapping>
<mapping std_arg="3" arg="3"></mapping>
</function>
Эти примеры показывают результат сопоставления определенных функций со стандартными функциями:
my_acos → acos:
Если используется сопоставление, User assertion чек становится зеленым. Проверка предполагает, что возвращаемое значение my_acos равно 0.
Перед отображением:
double x = my_acos(1.0);
assert(x <= 2.0);Спецификация сопоставления:
<function name="my_acos" std="acos"> </function>
После сопоставления:
double x = my_acos(1.0);
assert(x <= 2.0);
my_sqrt → sqrt:
Если используется сопоставление, Invalid use of standard library routine чек краснеет. В противном случае проверка не проверяет, является ли аргумент my_sqrt является неотрицательным.
Перед отображением:
res = my_sqrt(-1.0);
Спецификация сопоставления:
<function name="my_sqrt" std="sqrt"> </function>
После сопоставления:
res = my_sqrt(-1.0);my_lookup_table (аргумент 2) →__ps_lookup_table_clip (аргумент 1):
Если используется сопоставление, User assertion чек становится зеленым. Проверка предполагает, что возвращаемое значение my_lookup_table находится в диапазоне массива таблицы поиска table.
Перед отображением:
double table[3] = {1.1, 2.2, 3.3}
.
.
double res = my_lookup_table(u, table, bp);
assert(res >= 1.1 && res <= 3.3);Спецификация сопоставления:
<function name="my_lookup_table" std="__ps_lookup_table_clip">
<mapping std_arg="1" arg="2"></mapping>
</function>После сопоставления:
double table[3] = {1.1, 2.2, 3.3}
.
.
res_real = my_lookup_table(u, table9, bp);
assert(res_real >= 1.1 && res_real <= 3.3);
my_meminit →__ps_meminit:
Если используется сопоставление, Non-initialized local variable чек становится зеленым. При проверке предполагается, что все поля структуры x инициализированы с допустимыми значениями.
Перед отображением:
struct X {
int field1 ;
int field2 ;
};
.
.
struct X x;
my_meminit(&x, sizeof(struct X));
return x.field1;Спецификация сопоставления:
<function name="my_meminit" std="__ps_meminit">
<mapping std_arg="1" arg="1"></mapping>
<mapping std_arg="2" arg="2"></mapping>
</function>После сопоставления:
struct X {
int field1 ;
int field2 ;
};
.
.
struct X x;
my_meminit(&x, sizeof(struct X));
return x.field1;
my_meminit →__ps_meminit:
Если используется сопоставление, Non-initialized local variable чек краснеет. Проверка предполагает, что только поле field1 структуры x инициализирован с допустимыми значениями.
Перед отображением:
struct X {
int field1 ;
int field2 ;
};
.
.
struct X x;
my_meminit(&x, sizeof(int));
return x.field2;Спецификация сопоставления:
<function name="my_meminit" std="__ps_meminit"> </function>
После сопоставления:
struct X {
int field1 ;
int field2 ;
};
.
.
struct X x;
my_meminit(&x, sizeof(int));
return x.field2;