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