Main Content

Signal call from within signal handler

Nonpersistent signal handler calling signal() in Windows system causes race condition

Description

This defect occurs when you call the function signal() from a signal handler on Windows® platforms.

The defect is detected only if you specify a Visual Studio compiler. See Compiler (-compiler).

Risk

The function signal() associates a signal with a signal handler function. On platforms such as Windows, which removes this association after receiving the signal, you might call the function signal() again within the signal handler to re-establish the association.

However, this attempt to make a signal handler persistent is prone to race conditions. On Windows platforms, from the time the signal handler begins execution to when the signal function is called again, it is the default signal handling, SIG_DFL, that is active. If a second signal is received within this time window, you see the default signal handling and not the custom signal handler, but you might expect otherwise.

Fix

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

Examples

expand all

#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.

The issue is detected only if you specify a compiler such as visual15.x for the analysis.

Correction — Do Not Call signal() from Signal Handler

Avoid attempting to make a signal handler persistent on Windows. 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 */
            
        }
}
 

Result Information

Group: Programming
Language: C | C++
Default: On for handwritten code, off for generated code
Command-Line Syntax: SIG_HANDLER_CALLING_SIGNAL
Impact: Medium

Version History

Introduced in R2017b