exponenta event banner

-code-поведение-спецификации

Неточное отображение функции на стандартную функцию для точного анализа

Синтаксис

-code-behavior-specifications file

Описание

-code-behavior-specifications file позволяет связать определенное поведение с элементами кода и изменить результаты проверок этих элементов. Здесь, file - это XML-файл, который назначает определенные варианты поведения элементам кода, таким как функции.

Например, можно:

  • Сопоставьте функции библиотеки с соответствующими стандартными функциями, которые распознает Polyspace ®. Сопоставление со стандартными библиотечными функциями может помочь в повышении точности или автоматическом обнаружении новых потоков.

  • Укажите, что функция имеет особое поведение или должна подвергаться специальным проверкам.

    Например, можно указать, что функция должна принимать только адреса инициализированных переменных в качестве аргументов, или что функция не должна использоваться полностью.

При выполнении проверки из командной строки укажите абсолютный путь к XML-файлам или путь относительно папки, из которой выполняется команда. Если проверка выполняется из пользовательского интерфейса (только для настольных продуктов), укажите параметр вместе с абсолютным путем к XML-файлу в поле Другое. Посмотрите Other. Обратите внимание, что отчет, созданный на основе результатов анализа, показывает только использование этого параметра, а не сведения о том, какое поведение было связано с элементами кода.

Образец файла шаблона code-behavior-specifications-template.xml показывает синтаксис XML. Файл находится в polyspaceroot\polyspace\verifier\cxx\ где polyspaceroot является папкой установки Polyspace.

Если в качестве расширений кода в IDE используется Polyspace, введите эту опцию в файл опций анализа. См. файл параметров.

Использование опции для повышения точности

Синтаксис XML: <function name="custom_function" std="std_function"> </function>

Используйте эту запись в XML-файле, чтобы уменьшить количество проверок оранжевого цвета из неточного анализа программы поиска кода (или ложных негативов из неточного анализа программы поиска ошибок). Иногда проверка не анализирует определенные виды функций именно из-за внутренних ограничений статической проверки. В этих случаях, если вы находите стандартную функцию, которая является близким аналогом вашей функции, используйте это отображение. Хотя сама функция не анализируется, анализ более точен в местах, где вы называете функцию. Например, если проверка не может проанализировать вашу функцию cos32 точно и учитывает полный диапазон для его возвращаемого значения, сопоставьте его с cos функция для возвращаемого значения в [-1,1].

Проверка игнорирует тело вашей функции. Однако проверка эмулирует поведение функции следующими способами:

  • Проверка предполагает те же возвращаемые значения для функции, что и стандартная функция.

    Например, при отображении функции cos32 в стандартную функцию cos, проверка предполагает, что cos32 возвращает значения в [-1,1].

  • Проверка выполняется для тех же проблем, что и проверка со стандартной функцией.

    Например, при отображении функции acos32 в стандартную функцию acosInvalid 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,..,n6 для следующих параметров, чтобы указать ограничения на некоторые аспекты программы. Изменения влияют на проверку MISRA 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 и n8 чтобы указать, сколько символов должно сравниваться, чтобы определить, являются ли два идентификатора идентичными. Изменения влияют на проверку правил 5.x.

  • 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:

  1. Копировать файл code-behavior-specifications-template.xml от polyspaceroot\polyspace\verifier\cxx\ в другое место, например, "C:\Polyspace_projects\Common\Config_files". Измените разрешения на запись в файл.

  2. Чтобы преобразовать функцию в стандартную, измените содержимое XML-файла. Для отображения функции acos32 в стандартную библиотечную функцию acos, измените следующий код:

    <function name="my_lib_cos" std="acos"> </function>
    Кому:
    <function name="acos32" std="acos"> </function>

  3. Укажите расположение файла для проверки:

    • Проверка кода:

      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_acosacos:

    Если используется сопоставление, 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_sqrtsqrt:

    Если используется сопоставление, 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;

Представлен в R2016b