Missing unlock

Функция блокировки без разблокировала функцию

Описание

Этот дефект происходит когда:

  • Задача вызывает функцию блокировки.

  • Задача заканчивается без вызова разблокировать функции.

В многозадачном коде функция блокировки начинает критический раздел кода, и разблокировать функция заканчивает его. Когда задача, 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() 
{
    begin_critical_section();
    global_var = 0;
    end_critical_section();
}

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

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

ОпцияЗначение
Configure multitasking manually
Tasks (-entry-points)

my_taskсброс

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 вводит критический раздел через вызов begin_critical_section();. my_task концы, не вызывая end_critical_section.

Коррекция — обеспечивает, разблокировали

Одна возможная коррекция должна вызвать разблокировать функциональный end_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) {
      begin_critical_section();
      global_var ++;
      if(index%10==0) {
        global_var = 0;
        end_critical_section();
      }
      index++;
    }
}

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

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

my_taskсброс

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 вводит критический раздел через вызов begin_critical_section();. В итерации while цикл:

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

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

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

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

Коррекция — место разблокировало внешнее условие

Одна возможная коррекция должна вызвать разблокировать функциональный end_critical_section вне if условие.



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) {
      begin_critical_section();
      global_var ++;
      if(index%10==0) {
        global_var=0;
      }
      end_critical_section();
      index++;
    }
}
Коррекция — место разблокировало в каждом условном переходе

Другая возможная коррекция должна вызвать разблокировать функциональный end_critical_section в каждом ветви if условие.



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) {
      begin_critical_section();
      global_var ++;
      if(index%10==0) {
        global_var=0;
        end_critical_section();
      }
      else
        end_critical_section();
      index++;
    }
}

Проверяйте информацию

Группа: параллелизм
Язык: C | C++
Значение по умолчанию: On
Синтаксис командной строки: BAD_LOCK
Удар: высоко
ID CWE: 667
Введенный в R2014b