How to customize uncaught exception termination behavior?

泪湿孤枕 提交于 2019-12-05 11:19:04

Apart from actually catching the exceptions you care about, std::set_terminate() and std::current_exception() (C++11) ought to be enough to do something interesting.

The hook for customizing the handling of uncaught exceptions is catching the exceptions.

Based on @JonPurdy (accepted) answer, I experimented with this code that seems to work, at least with gcc 4.7.2 and clang 3.2 in Linux. I have no idea how robust or portable it is (comments welcomed), I tried not to make assumptions about the default terminate handler:

#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()"
}

Now I am experimenting with wrapping all the code in a class and call my_improve_terminate() before main so when including a certain file it becomes the new default.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!