Shared data access within signal handler

Доступ или модификация разделяемых данных вызывают противоречивое состояние

Описание

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

Риск

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

Фиксация

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

Примеры

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

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

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

Группа: Программирование
Язык: C | C++
Значение по умолчанию: На для рукописного кода, прочь для сгенерированного кода
Синтаксис командной строки: SIG_HANDLER_SHARED_OBJECT
Удар: носитель
ID CWE: 364, 413
Введенный в R2017b