How to prevent aborting in terminate handler depending of exception class - c++

I set the new terminate handler function with call:
std::set_terminate(TerminateHandler);
Terminate handler looks like this:
void TerminateHandler()
{
std::exception_ptr exptr = std::current_exception();
bool abort = true;
if(exptr != nullptr)
{
try
{
std::rethrow_exception(exptr);
}
catch(SoftMyException& ex){
std::cout << "Soft my exception";
abort = false;
}
catch(std::exception& ex)
{
std::cout << "Standard exception";
}
catch(...)
{
std::cout << "Terminated due to unknown exception";
}
}
else
{
std::cout << "Terminated due to unknown reason";
}
if(abort)
{
std::abort();
}
else{
std::cout << "Not abort";
}
}
These custom exceptions are set in the shared library and main program. I want to continue the work when SoftException arrives. SoftMyException class is defined like:
class SoftMyException : public std::exception{};
My program works well but still aborting event abort is not called.
Is here any option to call some function for restart the state inside terminate handler and continue with work without aborting depending of exception class?

Related

std::async and std::shared_future causes the program to fall

I am trying to run some function in asynchronous manner. For this purpose I wrote class called Core where I use std::async to run function in different thread and std::shared_future<int> to wait for this thread and possibly to get future result. This is code of test program:
#include <iostream>
#include <future>
class Core : public std::enable_shared_from_this<Core>
{
public:
Core()
: isRunning_(false) {
};
~Core() {
isRunning_ = false;
if (f_.valid())
{
f_.wait();
std::cout << "Result is: " << f_.get() << std::endl;
}
};
void Start() {
isRunning_ = true;
auto self(shared_from_this());
f_ = std::async(std::launch::async, [self, this]() {
try {
while (true) {
if (!isRunning_)
break;
std::cout << "Boom" << std::endl; // Error occurs here
std::this_thread::sleep_for(std::chrono::seconds(1));
}
}
catch (const std::exception& e) {
std::cerr << "Loop error:" << e.what();
}
return 999;
});
}
private:
std::shared_future<int> f_;
std::atomic<bool> isRunning_;
};
int main()
{
try {
std::shared_ptr<Core> load(new Core);
load->Start();
throw std::runtime_error("Generate error"); // Added in order to generate error
}
catch (const std::exception& e) {
std::cout << "Error occurred: " << e.what();
}
return 0;
}
Each time when I start this program it crashes at this line:
std::cout << "Boom" << std::endl; // Error occurs here
with this error:
That is debugger error and call stack which I managed to get during debugging:
Looks like Core destructor function doesn't call at all. Why is it happens? weird!!!
Could you tell me where is my mistake? Thanks.
When main thread returns from main() it starts tearing down the environment before terminating the whole process. All this while background thread is accessing objects there are being destroyed or have been destroyed already.
I am not sure what you are triying to achieve, but you are doing something wrong:
Your lambda should execute some work and return immediately after it is done e.g. you should never loop forever.
Your main thread should wait for your future to complete by calling std::future<T>::get().

c++ - Throwing multiple exceptions of the same type

So I've got a program with two exception. In both cases, I'd like to throw a string that can be caught in the main function and used in an error message. However, from what I know about them
try {
...
} catch(string msg) {
cerr << "..." << msg << "..." << endl;
} catch (string msg2) {
cerr << "..." << msg2 << "..." << endl;
}
isn't allowed. Is there any way I could do the above or something like it?
Thanks
I see two use cases:
1. You want two distinct types of errors.
Add exception classes derived from std::exception
class MyException1 : public std::exception
{
std::string message;
public:
MyException1(std::string const &what_arg) : message(what_arg) {}
MyException1(char const * what_arg) : message(what_arg) {}
const char* what() const { return message.c_str(); }
};
class MyException2 : public std::exception
{
std::string message;
public:
MyException2(std::string const &what_arg) : message(what_arg) {}
MyException2(char const * what_arg) : message(what_arg) {}
const char* what() const { return message.c_str(); }
};
and catch those:
try
{
int a = 5;
// do stuff
if (a == 7)
{
throw MyException1("Error 1 occured in because a == 7.");
}
else if (a == 5)
{
throw MyException1("Error 1 occured because a == 5.");
}
// do more stuff
if (a == 22)
{
throw MyException2("Error 2 occured in because a == 22.");
}
else if (a == 575)
{
throw MyException2("Error 2 occured because a == 575.");
}
}
catch (MyException1 &ex)
{
std::cout << "Exception 1: " << ex.what() << "\n";
}
catch (MyException2 &ex)
{
std::cout << "Exception 2: " << ex.what() << "\n";
}
Note: This is an easy but not the best design for a custom exception since std::string may throw and your program will be terminated.
2. You want two different error messages:
Use the appropriate type of exception from <stdexcept> header:
try
{
int a = 5;
// do stuff
if (a == 7)
{
throw std::runtime_error("Error 1 occured because a == 7.");
}
else if (a == 5)
{
throw std::runtime_error("Error 2 occured because a == 5.");
}
}
catch (const std::exception &ex)
{
std::cout << "Exception: " << ex.what() << "\n";
}
Note: The behaviour of case 1 can be emulated in case 2 without own types if the only desired behaviour is different output:
try
{
int a = 5;
// do stuff
if (a == 7)
{
throw std::runtime_error("Exception 1: Error 1 occured in because a == 7.");
}
else if (a == 5)
{
throw std::runtime_error("Exception 1: Error 1 occured because a == 5.");
}
// do more stuff
if (a == 22)
{
throw std::runtime_error("Exception 2: Error 2 occured in because a == 22.");
}
else if (a == 575)
{
throw std::runtime_error("Exception 2: Error 2 occured because a == 575.");
}
}
catch (const std::exception &ex)
{
std::cout << ex.what() << "\n";
}
Use std::runtime_error it has a constructor that takes a string. So pass it a different value when it is throw.
throw runtime_error( "msg1");
...
throw runtime_error("msg2");
Then when you catch just print the message in the object
...
catch( exception& e ){
cout << e.what() << endl;
}
First: Your compiler is supposed to issue a warning for that, because, the second catch will never be executed, because they are of exact signatures. Besides, you cannot have a second exception being thrown while the first is active ( exception thrown during stack unwinding that hasn't entered a catch block yet), else, the runtime will terminate your program.
Secondly: prefer to catch your exceptions by reference
Thirdly: Prefer to have your exception object fall in the inheritance tree of std::exception.
Lastly: What the hell are you trying to do?

C++ rethrow does not call custom terminate handler

I have used custom terminate handler which works fine if I call throw with a type or explicitly call terminate(), but if I use rethow i.e throw; , the custom terminate handler is not called, only default terminate handler is called causing the program to abort. Code confirms to C++03. Could anyone help me to find out the problem ? Thank you in advance
#include <iostream>
#include <exception>
using namespace std;
void myunexpected() {
cerr << "CUSTOM unexpected handler called ------ \n";
throw 0; // throws int (in exception-specification)
}
void myterminate () {
cerr << "CUSTOM terminate handler called ------ \n";
//abort(); // forces abnormal termination
exit(0);
}
void myfunction() throw (int) {
throw 'x'; // throws char (not in exception-specification)
}
int main(void) {
set_unexpected(myunexpected);
set_terminate(myterminate);
int a = 1;
try{
try {
myfunction();
}
catch (int) {
cerr << "caught int\n";
throw string("sree");
}
catch (...) { cerr << "caught some other exception type\n"; }
}
catch (string& s)
{
cerr << a << "caught STRING " << s << endl;
//throw 0; //ok --> implicitly calls terminate()-->myterminate
//terminate(); //ok --> explicitly calls terminate()-->myterminate
throw; //--------- Calls default throw Why ???
}
return 0;
}
OUTPUT
CUSTOM unexpected handler called ------
caught int
1caught STRING sree
This application has requested the Runtime to terminate it in an unusual way.
Please contact the application's support team for more information.
--------------------------------
Process exited after 8.238 seconds with return value 255
Press any key to continue . . .

Why does my program crash from an exception even though I catch that exception type?

I have this code:
printf("hello\n");
try
{
for ( unsigned i = 0; i < par.size(); i++ )
rep.delete_rev(par[i]);
}
catch(TriedToDeleteRoot e)
{
printf("catched 1 !\n");
}
catch(...) {
printf("catched sth else !\n");
}
printf("hahaha\n");
and this is what i have on output:
hello
terminate called after throwing an instance of 'TriedToDeleteRoot'
what(): Tried to delete root
why? TriedToDeleteRoot inherits from std::exception, and I don't have any idea what's wrong. Thanks.
EDIT:
this is how I throw an exception:
throw TriedToDeleteRoot();
My guess is the copy constructor for TriedToDeleteRoot is failing.
I suggest (as always) catching by const reference:
try
{
for ( unsigned i = 0; i < par.size(); i++ )
rep.delete_rev(par[i]);
}
catch(const TriedToDeleteRoot& e)
{
printf("caught 1 !\n");
}
or in the general case:
catch(const std::exception& e)
{
std::cerr << "exception: " << e.what() << std::endl;
}
You're observing that std::terminate is being called even though you have a try/catch that you expect to match the exception that's being thrown.
One reason this might happen is if you've managed to throw an exception whilst a previous exception is being handled. You can observe this with:
#include <iostream>
int main() {
try {
struct test {
~test() { throw 0; }
} test;
throw 0;
}
catch (...) {
std::cout << "Caught something" << std::endl;
}
}
On my system this calls abort() and prints:
terminate called after throwing an instance of 'int'
Notice that the catch(...) never gets hit because of this.
This simple example illustrates the easiest way to accidentally make that happen - throwing from within a destructor. My best guess from what you've shown is that this is what's happening. A debugger ought to confirm this for you though.

Catching all unhandled C++ exceptions?

Is there some way to catch exceptions which are otherwise unhandled (including those thrown outside the catch block)?
I'm not really concerned about all the normal cleanup stuff done with exceptions, just that I can catch it, write it to log/notify the user and exit the program, since the exceptions in these casese are generaly fatal, unrecoverable errors.
something like:
global_catch()
{
MessageBox(NULL,L"Fatal Error", L"A fatal error has occured. Sorry for any inconvience", MB_ICONERROR);
exit(-1);
}
global_catch(Exception *except)
{
MessageBox(NULL,L"Fatal Error", except->ToString(), MB_ICONERROR);
exit(-1);
}
This can be used to catch unexpected exceptions.
catch (...)
{
std::cout << "OMG! an unexpected exception has been caught" << std::endl;
}
Without a try catch block, I don't think you can catch exceptions, so structure your program so the exception thowing code is under the control of a try/catch.
Check out std::set_terminate()
Edit: Here's a full-fledged example with exception matching:
#include <iostream>
#include <exception>
#include <stdexcept>
struct FooException: std::runtime_error {
FooException(const std::string& what): std::runtime_error(what) {}
};
int main() {
std::set_terminate([]() {
try {
std::rethrow_exception(std::current_exception());
} catch (const FooException& e) {
std::cerr << "Unhandled FooException: " << e.what() << std::endl;
} catch (const std::exception& e) {
std::cerr << "Unhandled exception: " << e.what() << std::endl;
} catch (...) {
std::cerr << "Unhandled exception of unknown type" << std::endl;
}
std::abort();
});
throw FooException("Bad things have happened.");
// throw std::runtime_error("Bad things have happened.");
// throw 9001;
}
You can use SetUnhandledExceptionFilter on Windows, which will catch all unhandled SEH exceptions.
Generally this will be sufficient for all your problems as IIRC all the C++ exceptions are implemented as SEH.
Without any catch block, you won't catch any exceptions. You can have a catch(...) block in your main() (and its equivalent in each additional thread). In this catch block you can recover the exception details and you can do something about them, like logging and exit.
However, there are also downside about a general catch(...) block: the system finds that the exception has been handled by you, so it does not give any more help. On Unix/Linux, this help would constitute creating a CORE file, which you could load into the debugger and see the original location of the unexcepted exception. If you are handling it with catch(...) this information would be already lost.
On Windows, there are no CORE files, so I would suggest to have the catch(...) block. From that block, you would typically call a function to resurrect the actual exception:
std::string ResurrectException()
try {
throw;
} catch (const std::exception& e) {
return e.what();
} catch (your_custom_exception_type& e) {
return e.ToString();
} catch(...) {
return "Ünknown exception!";
}
}
int main() {
try {
// your code here
} catch(...) {
std::string message = ResurrectException();
std::cerr << "Fatal exception: " << message << "\n";
}
}
Update: This covers c++98 only.
From More Effective C++ by Meyers (pg 76), you could define a function that gets called when a function generates an exception that is not defined by its exception specification.
void convertUnexpected()
{
// You could redefine the exception here into a known exception
// throw UnexpectedException();
// ... or I suppose you could log an error and exit.
}
In your application register the function:
std::set_unexpected( convertUnexpected );
Your function convertUnexpected() will get called if a function generates an exception that is not defined by its exception specification... which means this only works if you are using exception specifications. ;(
Provided that C++11 is available, this approach may be used (see example from: http://en.cppreference.com/w/cpp/error/rethrow_exception):
#include <iostream>
#include <exception>
void onterminate() {
try {
auto unknown = std::current_exception();
if (unknown) {
std::rethrow_exception(unknown);
} else {
std::cerr << "normal termination" << std::endl;
}
} catch (const std::exception& e) { // for proper `std::` exceptions
std::cerr << "unexpected exception: " << e.what() << std::endl;
} catch (...) { // last resort for things like `throw 1;`
std::cerr << "unknown exception" << std::endl;
}
}
int main () {
std::set_terminate(onterminate); // set custom terminate handler
// code which may throw...
return 0;
}
This approach also allows you to customize console output for unhandled exceptions: to have something like this
unexpected exception: wrong input parameters
Aborted
instead of this:
terminate called after throwing an instance of 'std::logic_error'
what(): wrong input parameters
Aborted
This is what I always do in main()
int main()
{
try
{
// Do Work
}
catch(std::exception const& e)
{
Log(e.what());
// If you are feeling mad (not in main) you could rethrow!
}
catch(...)
{
Log("UNKNOWN EXCEPTION");
// If you are feeling mad (not in main) you could rethrow!
}
}
Use catch (...) in all of your exception barriers (not just the main thread). I suggest that you always rethrow (...) and redirect standard output/error to the log file, as you can't do meaningful RTTI on (...). OTOH, compiler like GCC will output a fairly detailed description about the unhandled exception: the type, the value of what() etc.