Main Content

Return from computational exception signal handler

Undefined behavior when signal handler returns normally from program error

Description

This defect occurs when a signal handler returns after catching a computational exception signal SIGFPE, SIGILL, or SIGSEGV.

Risk

A signal handler that returns normally from a computational exception is undefined behavior. Even if the handler attempts to fix the error that triggered the signal, the program can behave unexpectedly.

Fix

Check the validity of the values of your variables before the computation to avoid using a signal handler to catch exceptions. If you cannot avoid a handler to catch computation exception signals, call abort(), quick_exit(), or _Exit() in the handler to stop the program.

Examples

expand all

#include <errno.h>
#include <limits.h>
#include <signal.h>
#include <stdlib.h>

static volatile sig_atomic_t denom;
/* Declare signal handler to catch division by zero 
computation error. */
void sig_handler(int s)
{
    int s0 = s;
    if (denom == 0)
    {
        denom = 1;
    }
	/* Normal return from computation exception
	signal */
    return; 
}


long func(int v)
{
    denom = (sig_atomic_t)v;
       
        if (signal(SIGFPE, sig_handler) == SIG_ERR)
        {
            /* Handle error */
        }
		
	long result = 100 / (long)denom;
    return result;
}
        
      

In this example, sig_handler is declared to handle a division by zero computation error. The handler changes the value of denom if it is zero and returns, which is undefined behavior.

Correction — Call abort() to Terminate Program

After catching a computational exception, call abort() from sig_handler to exit the program without further error.

#include <errno.h>
#include <limits.h>
#include <signal.h>
#include <stdlib.h>

static volatile sig_atomic_t denom;
/* Declare signal handler to catch division by zero 
computation error. */

void sig_handler(int s)
{
    int s0 = s;
	/* call to abort() to exit the program */
    abort(); 
}

long func(int v)
{
    denom = (sig_atomic_t)v;
       
        if (signal(SIGFPE, sig_handler) == SIG_ERR)
        {
            /* Handle error */
        }
		
	long result = 100 / (long)denom;
    return result;
} 

Result Information

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

Version History

Introduced in R2017b