Пропавшие без вести разблокировали

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

Описание

Пропавшие без вести разблокировали, происходит когда:

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

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

В многозадачном коде функция блокировки начинает критический раздел кода, и разблокировать функция заканчивает его. Когда задача, 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, 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 вводит критический раздел через вызов 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, 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 вводит критический раздел через вызов 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++
Значение по умолчанию: на
Синтаксис командной строки: BAD_LOCK
Влияние: высоко
ID CWE: 667

Введенный в R2014b