Signal call from within signal handler

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

Описание

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

Дефект обнаруживается только при указании компилятора Visual Studio. См. Compiler (-compiler).

Риск

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

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

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

Не вызывайте 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 обработчики сигналов являются неперсистентными. Этот код может привести к условию гонки.

Проблема обнаруживается, только если вы задаете компилятор, такой как visual15.x для анализа.

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

Избегайте попыток сделать обработчик сигналов постоянным в Windows. Если ваш код требует использования обработчика постоянных сигналов на платформе 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++
По умолчанию: On для рукописного кода, off для сгенерированного кода
Синтаксис командной строки : SIG_HANDLER_CALLING_SIGNAL
Влияние: Средний
ИДЕНТИФИКАТОР CWE : 387, 474
Введенный в R2017b