CERT C++: ERR50-CPP

Резко не отключайте программу

Описание

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

Резко не отключайте программу.[1]

Реализация Polyspace

Это средство проверки проверяет на Неявный вызов, чтобы отключить () функцию.

Примеры

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

Проблема

Средство проверки отмечает ситуации, которые могут привести к вызову функционального std::terminate() неявно. Эти ситуации могут включать:

  • Исключение остается необработанным. Например:

    • При обрабатывании исключения это выходит через другую функцию, которая повышает необработанное исключение. Например, оператор выгоды или обработчик исключений вызывают другую функцию, которая повышает необработанное исключение.

    • Пустой throw оператор повышает необработанное исключение снова.

  • Деструктор класса повышает исключение.

  • Обработчик завершения, который передается std::atexit повышает необработанное исключение.

Риск

В зависимости от аппаратного и программного обеспечения, которое вы используете, вызывая terminate() неявно может привести к вызову std::abort(), который прерывает выполнение программы, не удаляя переменные в стеке. Такое аварийное завершение приводит к утечкам памяти и уязвимостям системы обеспечения безопасности.

Исправление

Избегать неявных вызовов terminate():

  • Избегайте необработанных исключений. Например, выполните операции main() или задача основные функции в try-catch блок. В блоках выгоды:

    • Обработайте исключения типа std::exception явным образом в соответствующих блоках выгоды.

    • Обработайте базовый класс исключений, являющихся результатом сторонних библиотек.

    • Обработайте непредвиденные исключительные ситуации в catch(...) блок.

  • Объявите деструкторы как noexcept и обработайте исключения в деструкторах.

  • Обработайте все исключения в обработчиках завершения.

Пример — неявный вызов terminate
#include <stdexcept>
int main(){   // Noncompliant
  try {
    // program code
  } catch (std::runtime_error& e) {
    // Handle runtime errors
  } catch (std::logic_error& e) {
    // Handle logic errors
  } catch (std::exception& e) {
    // Handle all expected exceptions
  }
  return 0;
}

В этом примере, main() определенные типы указателей исключений. Непредвиденная исключительная ситуация остается необработанной, приводя к неявному вызову функционального terminate это отключает программу резко. Поскольку main() вызовы terminate неявно, Polyspace® повышения этот дефект.

Коррекция — обрабатывает непредвиденные исключительные ситуации

Одна возможная коррекция должна включать catch(...) блокируйтесь, чтобы обработать непредвиденные исключительные ситуации так, чтобы программа могла выйти корректно.

#include <stdexcept>
[[noreturn]] void gracefulExit(){
	// unwind stack and report errors
	std::terminate();
}
int main()   // Compliant
{
  try {
    // program code
  } catch (std::runtime_error& e) {
    // Handle runtime errors
  } catch (std::logic_error& e) {
    // Handle logic errors
  } catch (std::exception& e) {
    // Handle all expected exceptions
  }
  catch(...){
	  //Exit gracefully
	  gracefulExit();
  }
  return 0;
}

Пример — необработанные исключения в обработчиках завершения

Обработчик завершения atexit_handler повышает неперехваченное исключение. Функциональный atexit_handler выполняется после основного выполнения концов. Необработанные исключения в этой функции не могут быть обработаны в другом месте, ведя к неявному вызову std::terminate(). Polyspace отмечает функцию.

#include <stdexcept>
void atexit_handler(){//Noncompliant
	throw std::runtime_error("Error in atexit function");
}
void main(){
	try{
		//...
		std::atexit(atexit_handler);
	}catch(...){
		
	}
}
Коррекция — обрабатывает все исключения в обработчиках завершения

Чтобы откорректировать проблему, используйте catch(...) блокируйтесь, чтобы обработать все исключения в обработчике завершения atexit_handler.

#include <stdexcept>
void atexit_handler(){
	try{
		//..
		throw std::runtime_error("Error in atexit function");
	}catch(...){
		//...
	}
}
void main(){
	try{
		//...
		std::atexit(atexit_handler);
	}catch(...){
		
	}
}

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

Группа: 08. Исключения и обработка ошибок (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". УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИЙ НИКАКОГО ВИДА, ИЛИ ОПИСАЛ ИЛИ ПОДРАЗУМЕВАЛ, ОТНОСИТЕЛЬНО ЛЮБОГО ВОПРОСА ВКЛЮЧАЯ, НО НЕ ОГРАНИЧИЛ, ГАРАНТИЯ ПРИГОДНОСТИ ДЛЯ ЦЕЛИ ИЛИ ВЫСОКОГО СПРОСА, ИСКЛЮЧИТЕЛЬНОСТИ, ИЛИ ЗАКАНЧИВАЕТСЯ ПОЛУЧЕННЫЙ ИЗ ИСПОЛЬЗОВАНИЯ МАТЕРИАЛА. УНИВЕРСИТЕТ КАРНЕГИ-МЕЛЛОН НЕ ДАЕТ ГАРАНТИИ НИКАКОГО ВИДА ОТНОСИТЕЛЬНО СВОБОДЫ ОТ ПАТЕНТА, ТОВАРНОГО ЗНАКА ИЛИ НАРУШЕНИЯ АВТОРСКОГО ПРАВА.

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