ISO/IEC TS 17961 [sigcall]

Вызывающий сигнал от обработчиков прерывания

Описание

Определение правила

Вызывающий сигнал от обработчиков прерывания сигнала.[1]

Реализация Polyspace

Эта проверка проверяет наличие вызова Signal из обработчика сигнала.

Примеры

расширить все

Проблема

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

Проверяйте информацию

Решимость: Undecidable
Введенный в R2019a

[1] Выдержки из стандарта «Техническая спецификация ISO/IEC TS 17961 - 2013-11-15» воспроизводятся с согласия АФНОР. Только оригинальный и полный текст стандарта, опубликованный AFNOR Editions - доступный через веб-сайт www.boutique.afnor.org - имеет нормативное значение.