Main Content

ISO/IEC TS 17961 [sigcall]

Calling signal from interruptible signal handlers

Description

Rule Definition

Calling signal from interruptible signal handlers.1

Polyspace Implementation

This checker checks for Signal call from within signal handler.

Examples

expand all

Issue

Signal call from within signal handler occurs when you call signal() from a nonpersistent signal handler on a Windows® platform.

Risk

A nonpersistent signal handler is reset after catching a signal. The handler does not catch subsequent signals unless the handler is reestablished by calling signal(). A nonpersistent signal handler on a Windows platform is reset to SIG_DFL. If another signal interrupts the execution of the handler, that signal can cause a race condition between SIG_DFL and the existing signal handler. A call to signal() can also result in an infinite loop inside the handler.

Fix

Do not call signal() from a signal handler on Windows platforms.

Example - signal() Called from Signal Handler
#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 */
}        
      

In this example, the definition of sig_handler() includes a call to signal() when the handler catches SIG_ERR. On Windows platforms, signal handlers are nonpersistent. This code can result in a race condition.

Correction — Do Not Call signal() from Signal Handler

If your code requires the use of a persistent signal handler on a Windows platform, use a persistent signal handler after performing a thorough risk analysis.

#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 */
            
        }
}
 

Check Information

Decidability: Undecidable

Version History

Introduced in R2019a


1 Extracts from the standard "ISO/IEC TS 17961 Technical Specification - 2013-11-15" are reproduced with the agreement of AFNOR. Only the original and complete text of the standard, as published by AFNOR Editions - accessible via the website www.boutique.afnor.org - has normative value.