Проблема
Вызов сигнала из обработчика сигнала происходит, когда вы вызываете signal()
от непроницаемого обработчика сигналов в Windows® платформы.
РискОбработчик неперсистентного сигнала сбрасывается после захвата сигнала. Обработчик не улавливает последующие сигналы, если обработчик не переустановлен вызовом signal()
. Неперсистентный обработчик сигнала на платформе Windows сбрасывается на SIG_DFL
. Если другой сигнал прерывает выполнение обработчика, этот сигнал может вызвать условие гонки между SIG_DFL
и существующий обработчик сигналов. Вызов signal()
может также привести к бесконечному циклу внутри обработчика.
ЗафиксироватьНе вызывайте signal()
от обработчика сигналов на платформах Windows.
Пример - signal()
Вызывается из обработчика сигнала#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 */
}
}