Обработка исключений в прекращении

У меня есть следующий обработчик завершения:

void on_terminate() 
{
    std::exception_ptr eptr = std::current_exception();
    if (eptr)
    {
        try
        {
            std::rethrow_exception(eptr);
        }
        catch (const std::exception& e) 
        {
            DBG_FAIL(e.what());        
        }
        catch (...) 
        {
            DBG_FAIL("Unknown exception.");  
        }
    }
    else
    {
        DBG_FAIL("Terminate was called.");
    }    
}

Я уже некоторое время использую этот обработчик, и я твердо верю, что он работал. Но в последнее время выясняется, что когда исключение выбрасывается без посторонней помощи, я по-прежнему "Terminate was called.", (Я все еще получаю полезный стек вызовов.)

Я испытываю проблему на VS2015 Up3 и еще не успел проверить другие компиляторы и платформы. (GCC на Cygwin еще не реализует exception_ptr.) Я делаю что-то в корне неправильно?

Учитывая следующий код:

int main(int argc, char* argv[]) 
{
    std::set_terminate(on_terminate);

    throw std::runtime_error("#yolo");
}

Вы можете проверить проблему.

Для полноты здесь вы можете найти мой dbg.h.

1 ответ

Решение

Не уверен, что стандарт говорит об этом, но он не работает и с VS2017. Вы можете получить желаемое поведение, выполнив:

int main(int argc, char* argv[]) try
{
    std::set_terminate(on_terminate);

    throw std::runtime_error("#yolo");
}
catch (...) {
    std::get_terminate()();
}

Который будет вызывать ваш метод завершения из улова, и std::current_exception() в вашем on_terminate потом будет работать.

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