Проблема
Вызов сигнала из обработчика сигнала происходит, когда вы вызываете 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 */
}
}