Как настроить поведение завершения необработанного исключения?

В g++ а также clang++ (по крайней мере в Linux) следующее типичное сообщение отображается после того, как исключение выдается и не перехватывается (неперехваченное исключение):

terminate called after throwing an instance of 'std::runtime_error'
what():  Bye

Например в:

#include<stdexcept>
int main(){
throw std::runtime_error("Bye");
}

Как настроить сообщение об ошибке, сохраняя полный доступ к сгенерированному исключению?

Документация (http://www.cplusplus.com/reference/exception/set_unexpected/) упоминает set_unexpected (а также set_terminate) но я не знаю, как unexpected_handle имеет реальный доступ к генерируемому исключению, например, для вызова e.what() или что-то другое.

ЗаметкаПричина этого в том, что я хочу настроить сообщение для более сложной иерархии классов исключений, в которой больше информации, чем просто what()и я хочу отобразить его, если выбрасывается исключение такого типа (но если std::exception& выбрасывается по умолчанию так же, как типичный.

Заметка 2В соответствии с двумя предложениями до сих пор «настраивайте необработанные исключения, перехватывая исключения». Будет выглядеть так, как следует из кода. Мне было интересно, если есть способ сделать то же самое, не добавляя try-catch блок для все main() код, который я пишу.

#include<stdexcept>
int main() try{
....
}catch(std::exception& e){
std::clog << "terminate called after throwing an instance of '" << typeid(e) << "'\n"<< "  what(): " << e.what() << '\n'
<< "otherinfo, like current time\n";
}catch(alternative_exception& e){
std::clog << "terminate called after throwing an instance of '" << typeid(e) << "'\n"<< "  what(): " << e.what() << '\n'
<< "  where(): " << e.where() << '\n'
<< "  how(): " << e.how() << '\n'
<< "othermember(): " << e.othermember() << '\n';
}

5

Решение

Кроме того, чтобы поймать исключения, о которых вы заботитесь, std::set_terminate() а также std::current_exception() (C ++ 11) должно быть достаточно, чтобы сделать что-то интересное.

2

Другие решения

Хук для настройки обработки необработанных исключений перехватывает исключения.

3

Основываясь на ответе @JonPurdy (принятом), я экспериментировал с этим кодом, который работает, по крайней мере, с gcc 4.7.2 и clang 3.2 в Linux. Я понятия не имею, насколько он устойчив или переносим (комментарии приветствуются), я старался не делать предположений о обработчике завершения по умолчанию:

#include<stdexcept>
#include<iostream>
#include<typeinfo> // for typeid

// a special exception, can be an abstract class, here it is concrete class to make the example shorter.
struct debug_exception : std::runtime_error{
std::string where_;
debug_exception(std::string what, std::string where) : std::runtime_error(what), where_(where){}
virtual const char* where() const{return where_.c_str();}
};

std::terminate_handler my_default_terminate;

void my_verbose_terminate_handler(){
try{
throw;
}catch(debug_exception& e){
std::cerr << "my_verbose_terminate_handler called after throwing an instance of "<< typeid(e).name() << std::endl; // or demangled
std::cerr << "  what(): "  << e.what()  << std::endl;
std::cerr << "  where(): " << e.where() << std::endl;
}catch(...){
my_default_terminate(); // probably __gnu_cxx::__verbose_terminate_handler();
}
}
std::terminate_handler my_improve_terminate(){
my_default_terminate = std::set_terminate(my_verbose_terminate_handler);
return my_default_terminate;
}

int main(){
my_improve_terminate();
//  throw 2; // says the default "terminate called after throwing an instance of 'int'"//  throw std::runtime_error("bye"); // says the default "terminate called ... what(): bye"throw debug_exception("Bye", __PRETTY_FUNCTION__); // says my_verbose_terminate_handler called ... what(): Bye, where(): int main()"}

Сейчас я экспериментирую с упаковкой всего кода в class и позвонить my_improve_terminate() до main поэтому при включении определенного файла он становится новым по умолчанию.

3
По вопросам рекламы [email protected]