Выбросить основные, т.е. не перехваченные результаты исключения в SIGSEGV

Учитывая код

#include <iostream>
#include <stdexcept>

class Test {
public:
    Test() { std::cout << "Constructor called" << std::endl; }
    ~Test() { std::cout << "Destructor called" << std::endl; }
};

int main() {
    Test obj1;

    try 
    {
        Test obj2;
        throw std::runtime_error("Exception thrown"); 
    } // Object 2 is destroyed here
    catch (...)
    {
        throw; // std::abort
    }
} // not reached (implementation defined), Object 1 destructor never called

Я понимаю, почему деструктор obj2 не вызывается, поскольку его реализация определена, если раскручивание стека происходит в случае неперехваченного исключения, но я не понимаю, почему на обычных платформах Linux это разрешено или думает, что оно должно завершиться с помощью SIGSEGV сигнал. Насколько я понимаю, следует ожидать SIGABRT.

@n.m.couldbeanAI Разве это не нарушает стандарт CPP?

Superlokkus 18.04.2024 10:00

[кроме.handle] «Если соответствующий обработчик не найден, вызывается функция std::terminate();» Судя по твоему богу, std::terminate действительно назывался. Стандарт, кажется, не определяет, что должно произойти дальше, поэтому я думаю, что убийство SIGSEGV допустимо. Вы можете получить такое же поведение, просто вызвав прекращение.

pptaszni 18.04.2024 10:05

Вы можете получить такое же поведение, если ваша программа просто вызывает std::abort(). Стандарт C++ гласит: «Вызывает ненормальное завершение программы», но не указывает, что это должен быть сигнал SIGABRT. std::abort регулируется POSIX, в котором говорится, что он должен генерировать сигнал SIGABRT. pubs.opengroup.org/onlinepubs/9699919799/functions/abort.htm‌​l

VLL 18.04.2024 10:08

Существует по крайней мере заголовок <csignal>, определяющий сигналы, и cppref.com немного неясно, требует ли только POSIX или cpp lang в целом std::abort использовать SIGABRT en.cppreference.com/w/cpp/utility/ программа/SIG_types

Superlokkus 18.04.2024 10:09
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
4
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это артефакт (/ошибка?) Compiler Explorer. SIGABRT становится SIGSEGV: https://github.com/compiler-explorer/compiler-explorer/issues/5224

Запуск на моем компьютере дает:

$ ./example ; echo "Program returned: $?"
Constructor called
Constructor called
Destructor called
terminate called after throwing an instance of 'std::runtime_error'
  what():  Exception thrown
Aborted
Program returned: 134

Даже в Compiler Explorer вы можете обработать SIGABRT, чтобы увидеть, что он все еще там, после него есть только SIGSEGV: https://godbolt.org/z/6dYsP5K5K

std::signal(SIGABRT, [](int) {
    std::cout << "Caught SIGABRT\n" << std::flush;
});
std::signal(SIGSEGV, [](int) {
    std::cout << "Caught SIGSEGV\n" << std::flush;
    std::_Exit(1);
});

Вывод компилятора:

Program returned: 1
terminate called after throwing an instance of 'std::runtime_error'
  what():  Exception thrown
Constructor called
Constructor called
Destructor called
Caught SIGABRT
Caught SIGSEGV

Мой компьютер:

$ ./example ; echo "Program returned: $?"
Constructor called
Constructor called
Destructor called
terminate called after throwing an instance of 'std::runtime_error'
  what():  Exception thrown
Caught SIGABRT
Aborted
Program returned: 134

Это то, что я получаю за один раз, не выполняя сначала это на своей машине™ :-)

Superlokkus 18.04.2024 10:19

Другие вопросы по теме

Разница между vsnprintf в Linux и Windows
Почему Listen() (до вызова Accept()) достаточно, чтобы приложение завершило трехстороннее рукопожатие?
Передача входных данных в запуск скрипта Python
Запуск сценария Python с VirtualEnv в качестве демона с использованием файла .system
Попытка передать «указатель на структуру данных» обработчику сигнала с помощью функции sigqueue из одного процесса в другой, используя структуру siginfo_t
Awk: попробуйте преобразовать строку временной метки во время эпохи Unix
Как я могу выполнить поиск значения с помощью подстроки, извлеченной из имени хоста в bash?
Чтение и запись более 4096 байт в/из STDIN
Могу ли я получить информацию о файловом дескрипторе из основного файла с помощью GDB?
Ошибка анализатора ржавчины: не удалось загрузить связанный проект: корень проекта должен указывать на Cargo.toml илиrust-project.json (корневой каталог имеет формат пути Windows)