CERT C: Rule ERR32-C

Не используйте неопределенные значения errno

Описание

Управляйте определением

Не используйте неопределенные значения errno. [1]

Реализация Polyspace

Это средство проверки проверяет на Неправильное употребление errno в обработчике сигнала.

Примеры

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

Проблема

Неправильное употребление errno в обработчике сигнала происходит, когда вы вызываете одну из этих функций в обработчике сигнала:

  • signal: Вы вызываете signal функция в обработчике сигнала и затем считала значение errno.

    Например, функция-обработчик сигнала handler вызовы signal и затем вызовы perror, который читает errno.

    void handler(int signum) {
      pfv old_handler = signal(signum, SIG_DFL);
      if (old_handler == SIG_ERR) {
        perror("SIGINT handler"); 
      }
    }

  • errno- установка функции POSIX®: Вы вызываете errno- функция установки POSIX в обработчике сигнала, но не восстанавливает errno при возврате из обработчика сигнала.

    Например, функция-обработчик сигнала handler вызовы waitpid, который изменяет errno, но не восстанавливает errno перед возвратом.

    void handler(int signum) {
      int rc = waitpid(-1, NULL, WNOHANG);
      if (ECHILD != errno) {
      }
    }

Риск

В каждом случае, который отмечает средство проверки, вы рискуете использовать неопределенное значение errno.

  • signal: Если вызов signal в обработчике сигнала перестал работать, значение errno неопределенно (см. Стандарт C11, Секунда. 7.14.1.1). Если вы используете определенное значение errno, вы видите неожиданные результаты.

  • errno- функция установки POSIX: errno- установка функции устанавливает errno onFailure. Если вы читаете errno после того, как обработчик сигнала называется, и сам обработчик сигнала вызывает errno- устанавливая функцию, вы видите неожиданные результаты.

Фиксация

Избегайте ситуаций, где вы рискуете использовать неопределенное значение errno.

  • signal: После вызова signal функция в обработчике сигнала, не читайте errno или используйте функцию, которая читает errno.

  • errno- функция установки POSIX: Прежде, чем вызвать errno- установка функции в обработчике сигнала, сохраните errno к временной переменной. Восстановите errno от этой переменной прежде, чем возвратиться из обработчика сигнала.

Пример - чтение errno После signal Вызовите в обработчике сигнала

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

#define fatal_error() abort()

void handler(int signum) {
    if (signal(signum, SIG_DFL) == SIG_ERR) {
        perror("SIGINT handler");
    }
}

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

В этом примере, функциональном handler называется, чтобы обработать SIGINT сигнал. В теле handler, signal функция вызвана. После этого вызова, значения errno неопределенно. Средство проверки повышает дефект когда perror функция вызвана потому что perror использует значение errno.

Коррекция — старается не читать errno После signal Вызвать

Одна возможная коррекция не должна читать errno после вызова signal функция в обработчике сигнала. Исправленный код здесь вызывает abort функция через fatal_error макрос вместо perror функция.

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

#define fatal_error() abort()

void handler(int signum) {
    if (signal(signum, SIG_DFL) == SIG_ERR) {
        fatal_error();
    }
} 

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

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

Группа: правило 12. Обработка ошибок (ERR)

Введенный в R2019a


[1]  Это программное обеспечение было создано MathWorks, включающим фрагменты: “Веб-сайт SEI CERT-C”, © 2017 Carnegie Mellon University, веб-сайт SEI CERT-C © 2017 Carnegie Mellon University”, CERT SEI C Кодирование Стандарта – Правил для Разработки безопасных, Надежных и Защищенных систем – 2 016 Выпусков”, © 2016 Carnegie Mellon University, and “CERT SEI Стандарт Кодирования C++ – Правил для Разработки безопасных, Надежных и Защищенных систем на C++ – 2 016 Выпусков” © 2016 Carnegie Mellon University, со специальным разрешением от его Института программной инженерии.

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

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