CERT C++: SIG35-C

Не возвращайтесь от обработчика сигнала вычислительных исключений

Описание

Определение правила

Не возвращайтесь от обработчика вычислительных сигналов исключения.[1]

Реализация Polyspace

Эта проверка проверяет возврат из обработчика вычислительных сигналов исключений.

Примеры

расширить все

Проблема

Возврат от обработчика сигнала вычислительных исключений происходит, когда обработчик сигнала возвращается после захвата сигнала вычислительных исключений 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;
} 

Проверяйте информацию

Группа: 49. Разное (MSC)
Введенный в R2019a

[1] Это программное обеспечение было создано MathWorks, включающее фрагменты: «Сайт SEI CERT-C», © 2017 Университет Карнеги Меллон, Веб-сайт SEI CERT-C + + © 2017 Университет Карнеги Меллон, "Стандарт кодирования SEI CERT C - Правила разработки безопасных, Надежные и безопасные системы - 2016 Edition ", © 2016 Университет Карнеги Меллон, и "Стандарт кодирования SEI CERT C++ - Правила разработки безопасных, Надежные и безопасные системы в C++ - 2016 Edition "© 2016 Университет Карнеги Меллон, с специального разрешения от его Института программной инженерии.

ЛЮБОЙ МАТЕРИАЛ УНИВЕРСИТЕТА КАРНЕГИ МЕЛЛОН И/ИЛИ ЕГО ИНЖЕНЕРНОГО ИНСТИТУТА ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ, СОДЕРЖАЩИЙСЯ В НАСТОЯЩЕМ ДОКУМЕНТЕ, ПОСТАВЛЯЕТСЯ НА БАЗИСЕ «КАК ЕСТЬ». УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ, ВЫРАЖЕННЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, В ОТНОШЕНИИ ЛЮБОГО ВОПРОСА, ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИВАЯСЬ, ГАРАНТИЮ ПРИГОДНОСТИ ДЛЯ ЦЕЛЕЙ ИЛИ КОММЕРЧЕСКОЙ ВЫГОДЫ, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ УНИВЕРСИТЕТ КАРНЕГИ МЕЛЛОН НЕ ДАЕТ НИКАКИХ ГАРАНТИЙ В ОТНОШЕНИИ СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКИХ ПРАВ.

Это программное обеспечение и связанная с ним документация не были рассмотрены и не одобрены Университетом Карнеги-Меллон или его Институтом программной инженерии.