Return from computational exception signal handler

Неопределенное поведение, когда обработчик сигнала обычно возвращается из ошибки в программе

Описание

Этот дефект происходит, когда обработчик сигнала возвращает после ловли вычислительного сигнала исключения SIGFPE, SIGILL, или SIGSEGV.

Риск

Обработчик сигнала, который обычно возвращается из вычислительного исключения, является неопределенным поведением. Даже если обработчик пытается зафиксировать ошибку, которая инициировала сигнал, программа может неожиданно вести себя.

Фиксация

Проверяйте валидность значений ваших переменных перед расчетом, чтобы избегать использования обработчика сигнала, чтобы отловить исключения. Если вы не можете избежать обработчика, чтобы отловить сигналы исключения расчета, вызовите abort(), quick_exit(), или _Exit() в обработчике, чтобы остановить программу.

Примеры

развернуть все

#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;
}
        
      

В этом примере, sig_handler как объявляют, обрабатывает ошибку расчета деления на нуль. Обработчик изменяет значение denom если это - нуль и возвращается, который является неопределенным поведением.

Коррекция — вызывает abort() отключать программу

После ловли вычислительного исключения вызовите abort() от sig_handler выходить из программы без дальнейшей ошибки.

#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;
} 

Информация о результате

Группа: Программирование
Язык: C | C++
Значение по умолчанию: на
Синтаксис командной строки: SIG_HANDLER_COMP_EXCP_RETURN
Удар: низко
ID CWE: 387

Введенный в R2017b