Signal call from within signal handler

Нестойкий обработчик сигнала, вызывая signal() в Windows система вызывает состояние состязания

Описание

Этот дефект происходит, когда вы вызываете signal() от нестойкого обработчика сигнала на платформе Windows®.

Риск

Нестойкий обработчик сигнала сбрасывается после ловли сигнала. Обработчик не отлавливает последующие сигналы, если обработчик не восстановлен путем вызова signal(). Нестойкий обработчик сигнала на платформе Windows сбрасывается к SIG_DFL. Если другой сигнал прерывает выполнение обработчика, тот сигнал может вызвать состояние состязания между SIG_DFL и существующий обработчик сигнала. Вызов signal() может также привести к бесконечному циклу в обработчике.

Фиксация

Не вызывайте signal() от обработчика сигнала на платформах Windows.

Примеры

развернуть все

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>



volatile sig_atomic_t e_flag = 0;

void sig_handler(int signum)
{
    int s0 = signum;
    e_flag = 1;
	
	/* Call signal() to reestablish sig_handler 
	upon receiving SIG_ERR. */
   
    if (signal(s0, sig_handler) == SIG_ERR) 
    {
        /* Handle error */       
    }
}

void func(void)
{
        if (signal(SIGINT, sig_handler) == SIG_ERR)
        {
            /* Handle error */
            
        }
  /* more code */
}        
      

В этом примере, определении sig_handler() включает вызов signal() когда обработчик отлавливает SIG_ERR. На платформах Windows обработчики сигнала являются нестойкими. Этот код может привести к состоянию состязания.

Коррекция — не вызывает signal() от обработчика сигнала

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

#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>



volatile sig_atomic_t e_flag = 0;


void sig_handler(int signum)
{
    int s0 = signum;
    e_flag = 1;
    /* No call to signal() */
}

int main(void)
{
    
        if (signal(SIGINT, sig_handler) == SIG_ERR)
        {
            /* Handle error */
            
        }
}
 

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

Группа: Программирование
Язык: C | C++
Значение по умолчанию: На для рукописного кода, прочь для сгенерированного кода
Синтаксис командной строки: SIG_HANDLER_CALLING_SIGNAL
Удар: носитель
ID CWE: 387, 474
Введенный в R2017b