How to customize uncaught exception termination behavior?
In g++ and clang++ (in Linux at least) the following typical message is shown after an exception is thrown and not catch (uncaught exception):
terminate called after throwing an instance of 'std::runtime_error'
what(): Bye
For example in:
#include<stdexcept>
int main(){
throw std::runtime_error("Bye");
}
How do I customize the error message while still having full access to the thrown exception?
The documentation (http://www.cplusplus.com/reference/exception/set_unexpected/) mentions set_unexpected (and set_terminate) but I don't know how the unexpected_handle has actual access to the exception being thrown, for example to call e.what() or something else.
Note: The reason behind this is that I want to customize the message for a more complicated exception class hierarchy that has more information than simple what(), and I want to display it if such type exception is thrown (but if a simple std::exception& is thrown the default is the same as the typical.
Note2: According to the two suggestions so far, "customize uncaught exceptions by catching the exceptions." Will look like what follows in the code. I was wondering if there is a way to do the same without adding a try-catch block to all main() code that I write.
#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 timen";
}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';
}
c++ exception-handling terminate
add a comment |
In g++ and clang++ (in Linux at least) the following typical message is shown after an exception is thrown and not catch (uncaught exception):
terminate called after throwing an instance of 'std::runtime_error'
what(): Bye
For example in:
#include<stdexcept>
int main(){
throw std::runtime_error("Bye");
}
How do I customize the error message while still having full access to the thrown exception?
The documentation (http://www.cplusplus.com/reference/exception/set_unexpected/) mentions set_unexpected (and set_terminate) but I don't know how the unexpected_handle has actual access to the exception being thrown, for example to call e.what() or something else.
Note: The reason behind this is that I want to customize the message for a more complicated exception class hierarchy that has more information than simple what(), and I want to display it if such type exception is thrown (but if a simple std::exception& is thrown the default is the same as the typical.
Note2: According to the two suggestions so far, "customize uncaught exceptions by catching the exceptions." Will look like what follows in the code. I was wondering if there is a way to do the same without adding a try-catch block to all main() code that I write.
#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 timen";
}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';
}
c++ exception-handling terminate
1
You may want to have a look at the boost_exception thing. Otherwise, why would you not just try/catch std::exception e and work from there? That's pretty much what the default does in Linux.
– Alexis Wilke
Jun 23 '13 at 9:45
Related: stackoverflow.com/questions/3774316/c-unhandled-exceptions
– celtschk
Jun 23 '13 at 19:44
add a comment |
In g++ and clang++ (in Linux at least) the following typical message is shown after an exception is thrown and not catch (uncaught exception):
terminate called after throwing an instance of 'std::runtime_error'
what(): Bye
For example in:
#include<stdexcept>
int main(){
throw std::runtime_error("Bye");
}
How do I customize the error message while still having full access to the thrown exception?
The documentation (http://www.cplusplus.com/reference/exception/set_unexpected/) mentions set_unexpected (and set_terminate) but I don't know how the unexpected_handle has actual access to the exception being thrown, for example to call e.what() or something else.
Note: The reason behind this is that I want to customize the message for a more complicated exception class hierarchy that has more information than simple what(), and I want to display it if such type exception is thrown (but if a simple std::exception& is thrown the default is the same as the typical.
Note2: According to the two suggestions so far, "customize uncaught exceptions by catching the exceptions." Will look like what follows in the code. I was wondering if there is a way to do the same without adding a try-catch block to all main() code that I write.
#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 timen";
}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';
}
c++ exception-handling terminate
In g++ and clang++ (in Linux at least) the following typical message is shown after an exception is thrown and not catch (uncaught exception):
terminate called after throwing an instance of 'std::runtime_error'
what(): Bye
For example in:
#include<stdexcept>
int main(){
throw std::runtime_error("Bye");
}
How do I customize the error message while still having full access to the thrown exception?
The documentation (http://www.cplusplus.com/reference/exception/set_unexpected/) mentions set_unexpected (and set_terminate) but I don't know how the unexpected_handle has actual access to the exception being thrown, for example to call e.what() or something else.
Note: The reason behind this is that I want to customize the message for a more complicated exception class hierarchy that has more information than simple what(), and I want to display it if such type exception is thrown (but if a simple std::exception& is thrown the default is the same as the typical.
Note2: According to the two suggestions so far, "customize uncaught exceptions by catching the exceptions." Will look like what follows in the code. I was wondering if there is a way to do the same without adding a try-catch block to all main() code that I write.
#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 timen";
}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';
}
c++ exception-handling terminate
c++ exception-handling terminate
edited Jun 23 '13 at 23:12
alfC
asked Jun 23 '13 at 7:55
alfCalfC
5,10522959
5,10522959
1
You may want to have a look at the boost_exception thing. Otherwise, why would you not just try/catch std::exception e and work from there? That's pretty much what the default does in Linux.
– Alexis Wilke
Jun 23 '13 at 9:45
Related: stackoverflow.com/questions/3774316/c-unhandled-exceptions
– celtschk
Jun 23 '13 at 19:44
add a comment |
1
You may want to have a look at the boost_exception thing. Otherwise, why would you not just try/catch std::exception e and work from there? That's pretty much what the default does in Linux.
– Alexis Wilke
Jun 23 '13 at 9:45
Related: stackoverflow.com/questions/3774316/c-unhandled-exceptions
– celtschk
Jun 23 '13 at 19:44
1
1
You may want to have a look at the boost_exception thing. Otherwise, why would you not just try/catch std::exception e and work from there? That's pretty much what the default does in Linux.
– Alexis Wilke
Jun 23 '13 at 9:45
You may want to have a look at the boost_exception thing. Otherwise, why would you not just try/catch std::exception e and work from there? That's pretty much what the default does in Linux.
– Alexis Wilke
Jun 23 '13 at 9:45
Related: stackoverflow.com/questions/3774316/c-unhandled-exceptions
– celtschk
Jun 23 '13 at 19:44
Related: stackoverflow.com/questions/3774316/c-unhandled-exceptions
– celtschk
Jun 23 '13 at 19:44
add a comment |
3 Answers
3
active
oldest
votes
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.
Thanks, I added an answer based on these tips. It seems I didn't need to usestd::current_exception.
– alfC
Jun 28 '13 at 21:06
add a comment |
The hook for customizing the handling of uncaught exceptions is catching the exceptions.
However there are some cases where you can't do that. Static object constructors, for example.
– celtschk
Jun 23 '13 at 19:41
@Pete, does it mean also to put atry-catcharound allmain()programs? Besides this being annoying, is celtschk a counter example where this doesn't work? (please see my edit).
– alfC
Jun 23 '13 at 19:45
@celtschk - function try blocks handle exceptions thrown from constructors.
– Pete Becker
Jun 24 '13 at 14:38
@PeteBecker: Only if you are the author of the class and therefore can write the constructor.
– celtschk
Jun 26 '13 at 18:16
@celtschk - or if you write a derived class that forwards to the constructors of the base type and catches thrown exceptions.
– Pete Becker
Jun 26 '13 at 18:32
|
show 4 more comments
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.
Notetypeid(e).name()is not always particularly legible.
– aschepler
Jun 28 '13 at 21:52
1
@aschepler, yes, I should demangle it, just as__gnu_cxx::__verbose_terminate_handlerdoes; I didn't want too make the example too long. Note added.
– alfC
Jun 28 '13 at 22:01
btw, I couldn't find the implementation of__gnu_cxx::__verbose_terminate_handler, the default termination handler in gnu's std. Where can I find it? is it a real function that one can look up?
– alfC
Jun 29 '13 at 4:26
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f17258733%2fhow-to-customize-uncaught-exception-termination-behavior%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
3 Answers
3
active
oldest
votes
3 Answers
3
active
oldest
votes
active
oldest
votes
active
oldest
votes
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.
Thanks, I added an answer based on these tips. It seems I didn't need to usestd::current_exception.
– alfC
Jun 28 '13 at 21:06
add a comment |
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.
Thanks, I added an answer based on these tips. It seems I didn't need to usestd::current_exception.
– alfC
Jun 28 '13 at 21:06
add a comment |
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.
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.
answered Jun 23 '13 at 20:00
Jon PurdyJon Purdy
38k768125
38k768125
Thanks, I added an answer based on these tips. It seems I didn't need to usestd::current_exception.
– alfC
Jun 28 '13 at 21:06
add a comment |
Thanks, I added an answer based on these tips. It seems I didn't need to usestd::current_exception.
– alfC
Jun 28 '13 at 21:06
Thanks, I added an answer based on these tips. It seems I didn't need to use
std::current_exception.– alfC
Jun 28 '13 at 21:06
Thanks, I added an answer based on these tips. It seems I didn't need to use
std::current_exception.– alfC
Jun 28 '13 at 21:06
add a comment |
The hook for customizing the handling of uncaught exceptions is catching the exceptions.
However there are some cases where you can't do that. Static object constructors, for example.
– celtschk
Jun 23 '13 at 19:41
@Pete, does it mean also to put atry-catcharound allmain()programs? Besides this being annoying, is celtschk a counter example where this doesn't work? (please see my edit).
– alfC
Jun 23 '13 at 19:45
@celtschk - function try blocks handle exceptions thrown from constructors.
– Pete Becker
Jun 24 '13 at 14:38
@PeteBecker: Only if you are the author of the class and therefore can write the constructor.
– celtschk
Jun 26 '13 at 18:16
@celtschk - or if you write a derived class that forwards to the constructors of the base type and catches thrown exceptions.
– Pete Becker
Jun 26 '13 at 18:32
|
show 4 more comments
The hook for customizing the handling of uncaught exceptions is catching the exceptions.
However there are some cases where you can't do that. Static object constructors, for example.
– celtschk
Jun 23 '13 at 19:41
@Pete, does it mean also to put atry-catcharound allmain()programs? Besides this being annoying, is celtschk a counter example where this doesn't work? (please see my edit).
– alfC
Jun 23 '13 at 19:45
@celtschk - function try blocks handle exceptions thrown from constructors.
– Pete Becker
Jun 24 '13 at 14:38
@PeteBecker: Only if you are the author of the class and therefore can write the constructor.
– celtschk
Jun 26 '13 at 18:16
@celtschk - or if you write a derived class that forwards to the constructors of the base type and catches thrown exceptions.
– Pete Becker
Jun 26 '13 at 18:32
|
show 4 more comments
The hook for customizing the handling of uncaught exceptions is catching the exceptions.
The hook for customizing the handling of uncaught exceptions is catching the exceptions.
answered Jun 23 '13 at 11:49
Pete BeckerPete Becker
57.5k440117
57.5k440117
However there are some cases where you can't do that. Static object constructors, for example.
– celtschk
Jun 23 '13 at 19:41
@Pete, does it mean also to put atry-catcharound allmain()programs? Besides this being annoying, is celtschk a counter example where this doesn't work? (please see my edit).
– alfC
Jun 23 '13 at 19:45
@celtschk - function try blocks handle exceptions thrown from constructors.
– Pete Becker
Jun 24 '13 at 14:38
@PeteBecker: Only if you are the author of the class and therefore can write the constructor.
– celtschk
Jun 26 '13 at 18:16
@celtschk - or if you write a derived class that forwards to the constructors of the base type and catches thrown exceptions.
– Pete Becker
Jun 26 '13 at 18:32
|
show 4 more comments
However there are some cases where you can't do that. Static object constructors, for example.
– celtschk
Jun 23 '13 at 19:41
@Pete, does it mean also to put atry-catcharound allmain()programs? Besides this being annoying, is celtschk a counter example where this doesn't work? (please see my edit).
– alfC
Jun 23 '13 at 19:45
@celtschk - function try blocks handle exceptions thrown from constructors.
– Pete Becker
Jun 24 '13 at 14:38
@PeteBecker: Only if you are the author of the class and therefore can write the constructor.
– celtschk
Jun 26 '13 at 18:16
@celtschk - or if you write a derived class that forwards to the constructors of the base type and catches thrown exceptions.
– Pete Becker
Jun 26 '13 at 18:32
However there are some cases where you can't do that. Static object constructors, for example.
– celtschk
Jun 23 '13 at 19:41
However there are some cases where you can't do that. Static object constructors, for example.
– celtschk
Jun 23 '13 at 19:41
@Pete, does it mean also to put a
try-catch around all main() programs? Besides this being annoying, is celtschk a counter example where this doesn't work? (please see my edit).– alfC
Jun 23 '13 at 19:45
@Pete, does it mean also to put a
try-catch around all main() programs? Besides this being annoying, is celtschk a counter example where this doesn't work? (please see my edit).– alfC
Jun 23 '13 at 19:45
@celtschk - function try blocks handle exceptions thrown from constructors.
– Pete Becker
Jun 24 '13 at 14:38
@celtschk - function try blocks handle exceptions thrown from constructors.
– Pete Becker
Jun 24 '13 at 14:38
@PeteBecker: Only if you are the author of the class and therefore can write the constructor.
– celtschk
Jun 26 '13 at 18:16
@PeteBecker: Only if you are the author of the class and therefore can write the constructor.
– celtschk
Jun 26 '13 at 18:16
@celtschk - or if you write a derived class that forwards to the constructors of the base type and catches thrown exceptions.
– Pete Becker
Jun 26 '13 at 18:32
@celtschk - or if you write a derived class that forwards to the constructors of the base type and catches thrown exceptions.
– Pete Becker
Jun 26 '13 at 18:32
|
show 4 more comments
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.
Notetypeid(e).name()is not always particularly legible.
– aschepler
Jun 28 '13 at 21:52
1
@aschepler, yes, I should demangle it, just as__gnu_cxx::__verbose_terminate_handlerdoes; I didn't want too make the example too long. Note added.
– alfC
Jun 28 '13 at 22:01
btw, I couldn't find the implementation of__gnu_cxx::__verbose_terminate_handler, the default termination handler in gnu's std. Where can I find it? is it a real function that one can look up?
– alfC
Jun 29 '13 at 4:26
add a comment |
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.
Notetypeid(e).name()is not always particularly legible.
– aschepler
Jun 28 '13 at 21:52
1
@aschepler, yes, I should demangle it, just as__gnu_cxx::__verbose_terminate_handlerdoes; I didn't want too make the example too long. Note added.
– alfC
Jun 28 '13 at 22:01
btw, I couldn't find the implementation of__gnu_cxx::__verbose_terminate_handler, the default termination handler in gnu's std. Where can I find it? is it a real function that one can look up?
– alfC
Jun 29 '13 at 4:26
add a comment |
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.
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.
edited Jun 28 '13 at 22:02
answered Jun 28 '13 at 21:05
alfCalfC
5,10522959
5,10522959
Notetypeid(e).name()is not always particularly legible.
– aschepler
Jun 28 '13 at 21:52
1
@aschepler, yes, I should demangle it, just as__gnu_cxx::__verbose_terminate_handlerdoes; I didn't want too make the example too long. Note added.
– alfC
Jun 28 '13 at 22:01
btw, I couldn't find the implementation of__gnu_cxx::__verbose_terminate_handler, the default termination handler in gnu's std. Where can I find it? is it a real function that one can look up?
– alfC
Jun 29 '13 at 4:26
add a comment |
Notetypeid(e).name()is not always particularly legible.
– aschepler
Jun 28 '13 at 21:52
1
@aschepler, yes, I should demangle it, just as__gnu_cxx::__verbose_terminate_handlerdoes; I didn't want too make the example too long. Note added.
– alfC
Jun 28 '13 at 22:01
btw, I couldn't find the implementation of__gnu_cxx::__verbose_terminate_handler, the default termination handler in gnu's std. Where can I find it? is it a real function that one can look up?
– alfC
Jun 29 '13 at 4:26
Note
typeid(e).name() is not always particularly legible.– aschepler
Jun 28 '13 at 21:52
Note
typeid(e).name() is not always particularly legible.– aschepler
Jun 28 '13 at 21:52
1
1
@aschepler, yes, I should demangle it, just as
__gnu_cxx::__verbose_terminate_handler does; I didn't want too make the example too long. Note added.– alfC
Jun 28 '13 at 22:01
@aschepler, yes, I should demangle it, just as
__gnu_cxx::__verbose_terminate_handler does; I didn't want too make the example too long. Note added.– alfC
Jun 28 '13 at 22:01
btw, I couldn't find the implementation of
__gnu_cxx::__verbose_terminate_handler, the default termination handler in gnu's std. Where can I find it? is it a real function that one can look up?– alfC
Jun 29 '13 at 4:26
btw, I couldn't find the implementation of
__gnu_cxx::__verbose_terminate_handler, the default termination handler in gnu's std. Where can I find it? is it a real function that one can look up?– alfC
Jun 29 '13 at 4:26
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f17258733%2fhow-to-customize-uncaught-exception-termination-behavior%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
You may want to have a look at the boost_exception thing. Otherwise, why would you not just try/catch std::exception e and work from there? That's pretty much what the default does in Linux.
– Alexis Wilke
Jun 23 '13 at 9:45
Related: stackoverflow.com/questions/3774316/c-unhandled-exceptions
– celtschk
Jun 23 '13 at 19:44