exponenta event banner

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

Доступ или изменение общих данных приводит к несогласованному состоянию

Описание

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

Риск

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

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

Чтобы получить доступ к общим объектам или изменить их в обработчике сигналов, убедитесь, что объекты не содержат блокировок, или, если они являются целыми числами, объявите их как 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
Воздействие: среднее
CWE ID: 364, 413
Представлен в R2017b