Missing lock

Разблокируйте функцию без функции блокировки

Описание

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

В многозадачном коде функция блокировки начинает критический раздел кода и функция разблокировки прекращает его. Когда задача my_task вызывает функцию блокировки my_lock, другие задачи, вызывающие my_lock необходимо подождать до my_task вызывает соответствующую функцию разблокировки. Polyspace® требует, чтобы функции блокировки и разблокировки имели форму void func(void).

Чтобы найти этот дефект, перед анализом необходимо задать опции многозадачности. Чтобы задать эти опции, на панели Configuration выберите Multitasking.

Риск

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

Зафиксировать

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

См. примеры исправлений ниже. Чтобы избежать проблемы, можно следовать практике вызова функций блокировки и разблокировки в том же модуле на том же уровне абстракции. Например, в этом примере func вызывает функцию блокировки и разблокировки на том же уровне, но func2 не делает.

void func() {
  my_lock();
  {
    ...
  }
  my_unlock();
}

void func2() {
  {
   my_lock();
   ...
  }
  my_unlock();
}

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

Примеры

расширить все



void begin_critical_section(void);
void end_critical_section(void);

int global_var;

void reset(void) 
{
  begin_critical_section();
  global_var = 0;
  end_critical_section();
}

void my_task(void)
{
  global_var += 1;
  end_critical_section();
}

В этом примере, чтобы эмулировать поведение в многозадачном режиме, вы должны задать следующие опции:

ОпцияСпецификация
Configure multitasking manually
Tasks (-entry-points)

my_task, reset

Critical section details (-critical-section-begin -critical-section-end)Starting routineEnding routine
begin_critical_sectionend_critical_section

В командной строке можно использовать следующее:

polyspace-bug-finder
   -entry-points my_task,reset
   -critical-section-begin begin_critical_section:cs1
   -critical-section-end end_critical_section:cs1

Пример имеет две точки входа, my_task и reset. my_task вызывает end_critical_section перед вызовом begin_critical_section.

Коррекция - Обеспечьте блокировку

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



void begin_critical_section(void);
void end_critical_section(void);

int global_var;

void reset(void) 
{
  begin_critical_section();
  global_var = 0;
  end_critical_section();
}

void my_task(void)
{
    begin_critical_section();
    global_var += 1;
    end_critical_section();
}


void begin_critical_section(void);
void end_critical_section(void);

int global_var;

void reset() {
    begin_critical_section();
    global_var=0;
    end_critical_section();
}

void my_task(void) {
    int index=0;
    volatile int numCycles;
    
    while(numCycles) {
      if(index%10==0) {
        begin_critical_section();
        global_var ++;  
      }
      end_critical_section(); 
      index++;
    }
}

В этом примере, чтобы эмулировать поведение в многозадачном режиме, вы должны задать следующие опции:

ОпцияСпецификация
Configure multitasking manually
Tasks (-entry-points)

my_task, reset

Critical section details (-critical-section-begin -critical-section-end)Starting routineEnding routine
begin_critical_sectionend_critical_section

В командной строке можно использовать следующее:

polyspace-bug-finder
   -entry-points my_task,reset
   -critical-section-begin begin_critical_section:cs1
   -critical-section-end end_critical_section:cs1

Пример имеет две точки входа, my_task и reset.

В while цикл, my_task оставляет критический раздел через вызов end_critical_section();. В итерации while цикл:

  • Если my_task входит в if ветвь условия, критический раздел начинается через вызов begin_critical_section.

  • Если my_task не вводит if условие ветви и покидает while цикл, критический раздел не начинается. Поэтому возникает Missing lock дефект.

  • Если my_task не вводит if ветвь условия и продолжается до следующей итерации while цикл, функция разблокировки end_critical_section вызывается снова. Возникает Double unlock дефект.

Потому что numCycles является volatile переменная, она может взять любое значение. Возможен любой из вышеуказанных случаев. Поэтому на вызове появляются дефект Missing lock и дефект Double unlock end_critical_section.

Информация о результатах

Группа: Параллелизм
Язык: C | C++
По умолчанию: On
Синтаксис командной строки: BAD_UNLOCK
Влияние: Средний
ИДЕНТИФИКАТОР CWE: 832
Введенный в R2014b