The following code just hangs without returning control to the shell, printing only the following message:
"terminate called after throwing an instance of std::runtime_error"
#include <stdexcept>
int main() { throw std::runtime_error("exception"); return 0; }
Why doesn't this abort the process and return control to the shell?
Related
I'm using MinGW gcc (or g++) 7.1.0 on Windows 10.
Normally, throwing an std::runtime_error shows information like this:
terminate called after throwing an instance of 'std::runtime_error'
what(): MESSAGE
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
But the following code only shows the last two lines, and the what() information is lost:
#include <stdexcept>
using namespace std;
int main() {
try {
throw runtime_error("MESSAGE");
} catch (...) {
throw;
}
}
So the code above only outputs:
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
The same thing happens if I replace ... with const exception&, const runtime_error& (or without const, without &, or without both).
As I know, throw; rethrows the current caught exception. So why isn't what() shown?
What makes you think that rethrowing exception discards the information given by 'what()'? You never inspect what what() returns after rethrowing. This application has requested... message is shown because you uncaught exception caused program to be terminated. what() content is not supposed to be printed automatically.
You can print value return by what() without any problem:
#include <stdexcept>
#include <iostream>
int main()
{
try
{
try
{
throw ::std::runtime_error("MESSAGE");
}
catch (...)
{
throw;
}
}
catch(::std::exception const & exception)
{
::std::cout << exception.what() << ::std::endl;
}
}
I have read that one can call std::set_terminate() to use own function as global exception handler, which catches all unhandled exceptions.
Simplified code of my program:
#include <exception>
#include <stdexcept>
#include <iostream>
void my_terminate_handler()
{
std::cerr << "Terminate handler" << std::endl;
std::cin.get();
std::abort();
}
int main()
{
std::set_terminate(my_terminate_handler);
int i = 1;
i--;
std::cout << 1/i << std::endl;
return 0;
}
Why my_terminate_handler() never invoked? Both in VC++ 2013, 2015 RC and gcc++-4.8.
The terminate handler will be called if the program calls terminate. This can happen for various reasons - including an uncaught exception - but division by zero isn't one of those reasons. That gives undefined behaviour; typically, it raises a signal (not a C++ exception), and you'd need to install a signal handler, not a terminate handler, to catch that.
Because there is no uncaught exception in your code. Add one and it gets executed:
#include <exception>
#include <stdexcept>
#include <iostream>
void my_terminate_handler()
{
std::cerr << "Terminate handler" << std::endl;
}
int main()
{
std::set_terminate(my_terminate_handler);
throw "cake";
}
From Linux I know that in case a C++ program throws an exception, the exception type and message are printed on the terminal while the program dies. On mac, however, the only thing you get is:
libc++abi.dylib: terminate called throwing an exception
Abort trap: 6
Of course I could run the program in a debugger, but that's usually much more overhead just to see the exception type and message.
Is there any way to enable exception type and message printing on mac with any magic command?
Edit: I know what the correct way is to handle such situations with exception handling. It is more out of curiosity to find out whether the linux behavior can be reproduced on mac.
If you want to guarantee the information of a C++ exception is printed to the console you can add a try/catch block in main() like below.
#include <exception>
#include <iostream>
int main(int argc, char* argv[])
{
try { return mymain(argc, argv); }
catch(std::exception& e)
{
std::cout << "Unhandled exception thrown: " << e.what() << std::endl;
}
}
i am using a visual studio c++ compiler,& during my study on exception handling,i came across a number of features that can't be supported by visual c++ compiler,
like controlling the exceptions that can be thrown out of a function.
also i was unable to modify the functioning of terminate() using set_terminate() .
is it a specification too for visual c++ to modify terminate()?...& if so,then can anyone explain that why microsoft is creating these specifications in its compilers?...:-x
what do you mean you were unable to modify terminate
have you tried something like this ?
// set_terminate example
#include <iostream>
#include <exception>
#include <cstdlib>
using namespace std;
void myterminate () {
cerr << "terminate handler called\n";
abort(); // forces abnormal termination
}
int main (void) {
set_terminate (myterminate);
throw 0; // unhandled exception: calls terminate handler
return 0;
}
Don't try to run from VS. Compile and exec from command line.
I have the following code taken from cplusplus.com:
// set_terminate example
#include <iostream>
#include <exception>
#include <cstdlib>
using namespace std;
void myterminate () {
cout << "terminate handler called\n";
abort(); // forces abnormal termination
}
int main (void) {
set_terminate (myterminate);
throw 0; // unhandled exception: calls terminate handler
return 0;
}
As there is unhandled exception in the code, it needs to call myterminate() function which is set as terminate handler and supposed to override the default terminate handler.
The program is crashing but not calling myterminate(). I am using Visual C++ 2008 Express Edition.
What's the issue with the code?
One possibility - if you are running the program inside VC++ debugger, the debugger catches unhandled exceptions and it might not return control back to the running program to run myterminate. Try to run your program outside Visual C++.