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

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

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

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

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

Поместите курсор на оператор dereference.

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

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

    В следующем примере ptr можно NULL при дереферинге.

    Возможное исправление: Dereference 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.

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

    • Этот 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®:: правило 17.4 2004 или MISRA C: 2012 правило 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, которое происходит ранее в коде. Если предположение не имеет значения true в вашем случае, добавьте комментарий или обоснование в свой результат или код. Смотрите Адрес Результаты Polyspace через исправления ошибок или обоснования.

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

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

    Поэтому разыменование указателя происходит оранжевым цветом.

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

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

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

Для получения дополнительной информации смотрите Допущения анализа Code Prover.

Примечание

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