Рассмотрите и зафиксируйте незаконно разыменованные проверки указателя

Выполните один или несколько из этих шагов, пока вы не определите фиксацию для проверки Illegally dereferenced pointer. Существует несколько способов зафиксировать эту проверку. Для описания проверки и примеров кода, смотрите Illegally dereferenced pointer.

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

Для общего рабочего процесса, который применяется ко всем проверкам, смотрите, Интерпретируют Результаты Polyspace Code Prover.

Шаг 1: интерпретируйте информацию о проверке

Установите свой курсор на разыменовать оператор.

Получите следующую информацию из подсказки:

  • Может ли указателем быть NULL.

    В следующем примере ptr может быть NULL, когда разыменовано.

    Возможная фиксация: Разыменуйте ptr, только если это не NULL.

    if(ptr !=NULL)
        *ptr = 1;
    else 
        /* Alternate action */

  • Указывает ли указатель на динамически выделенную память.

    В следующем примере ptr может указать на динамически выделенную память. Возможно, что оператор динамического выделения памяти возвращает NULL.

    Возможная фиксация: Проверяйте возвращаемое значение оператора выделения памяти для NULL.

    ptr = (char*) malloc(i);
    if(ptr==NULL)
      /* Error handling*/
    else {
      .
    	.
    	*ptr=0;
    	.
    	.
    }

  • Указывает ли указатель внешние позволенные границы. Указатель указывает внешние границы, когда сумма размера указателя и смещения больше, чем buffer size.

    В следующем примере размер смещения (4 096 байтов) вместе с размером указателя (4 байта) больше, чем buffer size (4 096 байтов). Если указатель указывает на массив:

    • Buffer size является размером массивов.

    • Смещение является различием между началом массива и текущим местоположением указателя.

    Возможная фиксация: Займитесь расследованиями, почему указатель указывает вне позволенного буфера.

  • Может ли указатель указать внешние позволенные границы, потому что buffer size неизвестен.

    В следующем примере buffer size неизвестен.

    Возможная фиксация: Займитесь расследованиями, присвоен ли указатель:

    • Возвращаемое значение неопределенной функции.

    • Возвращаемое значение функции динамического выделения памяти. Иногда, Polyspace не может определить buffer size от динамического выделения памяти.

    • Другой указатель другого типа, например, void*.

  • Вероятная первопричина для недопустимого указателя разыменовывает, если обозначено в подсказке.

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

    Возможная фиксация: Чтобы избежать незаконно разыменованного указателя, ограничьте возвращаемое значение getAddress. Например, укажите, что getAddress возвращает указатель на массив с 10 элементами. Для получения дополнительной информации смотрите Заблокированные Функции.

Шаг 2: определите первопричину проверки

Выберите проверку и отметьте информацию о панели Result Details.

  • Если панель Result Details показывает последовательность инструкций, которые приводят к проверке, выбирают каждую инструкцию и прослеживают до первопричины.

  • Если панель Result Details показывает, что номер строки вероятной причины для проверки, в пользовательском интерфейсе Polyspace, щелкает правой кнопкой по панели Source. Выберите Go To Line.

  • В противном случае, на основе природы ошибки, используйте один из следующих методов, чтобы найти первопричину. Можно выполнить следующие шаги в пользовательском интерфейсе Polyspace только.

    ОшибкаКак найти первопричину
    Указателем может быть NULL.

    Найдите путь к выполнению, где указатель присвоен значение NULL или не присвоил определенный адрес.

    1. Щелкните правой кнопкой по указателю и выберите Search For All References.

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

    3. Для каждого экземпляра, на панели Source, устанавливают ваш курсор на указатель. Подсказка указывает, может ли указателем быть NULL.

      Возможная фиксация: Если указателем может быть NULL, поместить проверку на NULL сразу после присвоения.

      if(ptr==NULL)
        /* Error handling*/
      else {
        .
        .
      	}
    4. Если указателем не является NULL, смотрите, происходит ли присвоение только в ответвлении условного оператора. Займитесь расследованиями, когда то ответвление не выполнится.

      Возможная фиксация: Присвойте допустимый адрес указателю во всех ответвлениях условного оператора.

    Указатель может указать на динамически выделенную память.

    Идентифицируйте, где выделение происходит.

    1. Щелкните правой кнопкой по указателю и выберите Search For All References.

    2. Найдите предыдущий экземпляр, где указатель получает значение от функции динамического выделения памяти, такой как malloc.

      Возможная фиксация: После выделения протестируйте указатель на NULL.

    Указатель может указать внешние границы, позволенные буфером.

    1. Найдите позволенный буфер.

      1. На вкладке Search введите имя переменной, на которую указывает указатель. У вас уже есть это имя от подсказки на проверке.

      2. Ищите определение переменной. Как правило, это - первый результат поиска.

        Если переменная является массивом, отметьте размер массивов. Если переменная является структурой, ищите имя типа структуры на вкладке Search и найдите определение структуры. Отметьте размер поля структуры, на которое указывает указатель.

    2. Узнайте, почему указатель указывает вне позволенного буфера.

      1. Щелкните правой кнопкой по указателю и выберите Search For All References.

      2. Идентифицируйте любой шаг или декремент указателя. Смотрите, намеревались ли вы сделать шаг или декремент.

        Возможная фиксация: Удалите непреднамеренную адресную арифметику с указателями. Чтобы избежать адресной арифметики с указателями, которая берет указатель вне позволенного буфера, используйте ссылочный указатель, чтобы сохранить его начальное значение. После каждой арифметической операции на указателе сравните его со ссылочным указателем, чтобы видеть, ли различие вне позволенного буфера.

Шаг 3: ищите частые причины проверки

Ищите частые причины проверки Illegally dereferenced pointer.

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

    Чтобы избежать использования адресной арифметики с указателями в вашем коде, ищите нарушения MISRA C®: 2 004 правила 17.4 или MISRA C: 2 012 правил 18.4. Для получения дополнительной информации смотрите Проверку на Кодирование Стандартных Нарушений.

  • Смотрите, используете ли вы указатели для перемещения через поля структуры.

    Polyspace не позволяет указателю на одно поле структуры указывать на другое поле. Чтобы позволить это поведение, используйте опцию Enable pointer arithmetic across fields (-allow-ptr-arith-on-struct).

  • Смотрите, разыменовываете ли вы указатель, который указывает на структуру, но не имеет достаточной памяти для всех ее полей. Такой указатель обычно следует из преобразования типа указателя на меньшую структуру.

    Polyspace не позволяет такому разыменовывать. Чтобы позволить это поведение, используйте опцию Allow incomplete or partial allocation of structures (-size-in-bytes).

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

    Смотрите, вызывает ли один конкретный вызов оранжевую проверку. Для примера смотрите, Идентифицируют Вызов функции с Ошибкой времени выполнения.

  • Смотрите, выполняете ли вы бросок между двумя указателями несовместимых размеров.

Шаг 4: проследите проверку до предположения Polyspace

Смотрите, можно ли проследить оранжевую проверку до предположения Polyspace, которое происходит ранее в коде. Если предположение не сохраняется в вашем случае, добавьте комментарий или выравнивание в вашем результате или коде. Смотрите Результаты Polyspace Адреса Через Исправления ошибок или Комментарии.

Например, указатель получает адрес от неопределенной функции. Затем:

  1. Polyspace принимает, что функция может возвратить NULL.

    Поэтому указатель разыменовывает, является оранжевым.

  2. Polyspace также принимает позволенный buffer size на основе типа указателя.

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

  3. Если вы знаете, что функция возвращает non-NULL значение или если вы знаете истинный позволенный буфер, добавьте комментарий и выравнивание в вашем коде, описывающем, почему вы не изменили свой код.

Для получения дополнительной информации смотрите Аналитические Предположения Программы автоматического доказательства Кода.

Примечание

Прежде, чем выровнять по ширине оранжевую проверку, рассмотрите тщательно, можно ли улучшить проект кодирования.