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++
По умолчанию: On для рукописного кода, off для сгенерированного кода
Синтаксис командной строки : SIG_HANDLER_COMP_EXCP_RETURN
Влияние: Низкое
ИДЕНТИФИКАТОР CWE : 387
Введенный в R2017b