ПроблемаСредство проверки отмечает ситуации, которые могут привести к вызову функционального 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(...){
}
}