CERT C: Rule SIG31-C

Не получайте доступ к общим объектам в обработчиках сигналов

Описание

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

Не получайте доступ к общим объектам в обработчиках сигналов.[1]

Реализация Polyspace

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

Примеры

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

Проблема

Доступ к разделяемым данным внутри обработчика сигналов происходит, когда вы получаете доступ или изменяете общий объект внутри обработчика сигналов.

Риск

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

Зафиксировать

Чтобы получить доступ или изменить общие объекты внутри обработчика сигнала, проверяйте, что объекты являются безблокировочными атомарными, или, если они являются целыми числами, объявляйте их как volatile sig_atomic_t.

Пример - int Переменный доступ в обработчике сигналов
#include <signal.h>
#include <stdlib.h>
#include <string.h>

/* declare global variable. */
int e_flag;

void sig_handler(int signum)
{
	/* Signal handler accesses variable that is not
	of type volatile sig_atomic_t. */
    e_flag = signum; 
}

int func(void)
{
    if (signal(SIGINT, sig_handler) == SIG_ERR)
    {
        /* Handle error */
        abort();
    }
    /* Program code */
    if (raise(SIGINT) != 0)
    {
        /* Handle error */
        abort();
    }
    /* More code */
    return 0;
}
        
      

В этом примере sig_handler обращается к e_flag, переменная типа int. Параллельный доступ другой функции может покинуть e_flag в несогласованном состоянии.

Коррекция - Объявление переменной типа volatile sig_atomic_t

Прежде чем вы получите доступ к общей переменной от обработчика сигнала, объявите переменную с типом volatile sig_atomic_t вместо int. Вы можете безопасно получить доступ к переменным этого типа асинхронно.

#include <signal.h>
#include <stdlib.h>
#include <string.h>

/* Declare variable of type volatile sig_atomic_t. */
volatile sig_atomic_t e_flag;
void sig_handler(int signum)
{
	/* Use variable of proper type inside signal handler. */
    e_flag = signum;
    
}

int func(void)
{
    if (signal(SIGINT, sig_handler) == SIG_ERR)
    {
        /* Handle error */
        abort();
    }
    /* Program code */
    if (raise(SIGINT) != 0)
    {
        /* Handle error */
        abort();
    }
    /* More code */
    return 0;
} 

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

Группа: Правило 11. Сигналы (SIG)
Введенный в R2019a

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

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

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