exponenta event banner

Вызов сигнала из обработчика сигнала

Вызов несуществующего обработчика сигнала 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++
По умолчанию: Вкл для рукописного кода, выкл для сгенерированного кода
Синтаксис командной строки: SIG_HANDLER_CALLING_SIGNAL
Воздействие: среднее
CWE ID: 387, 474
Представлен в R2017b