C++ rethrow does not call custom terminate handler - c++

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 . . .

Related

How to prevent aborting in terminate handler depending of exception class

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?

VC++ std::current_exception returns null in uncaught exception

It seems that the default terminate handler in Windows does not print the ex.what() of the exception that caused it.
As a workaround I thought to implement a custom terminate handler to print the exception:
#include <iostream>
void term_func()
{
std::cout << "term_func was called by terminate.(1)" << std::endl;
std::exception_ptr eptr = std::current_exception();
try
{
if(eptr)
{
std::rethrow_exception(eptr);
}
}
catch(const std::exception& e)
{
std::cout << "Caught exception \"" << e.what() << "\"\n";
}
std::cout << "term_func was called by terminate.(2)" << std::endl;
exit(-1);
}
int main(int argc, char **argv)
{
std::set_terminate(term_func);
throw std::runtime_error("is windows broken?");
}
This works well in GCC and Clang++ (prints also the content of the exception), however in VC++ it only prints:
term_func was called by terminate.(1)
term_func was called by terminate.(2)
Now, are there any workarounds to this? Or to the initial problem?

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().

Throwing C++ exceptions from a hardware exception handler. Why does -fnon-call-exceptions not behave as expected?

I had this funny idea last night, to trap hardware exceptions and throw a C++ exception instead. Thought that might be useful for things like FPU exceptions, which normally either crash, or silently return NaN and then cause unexpected behaviour. A C++ exception would be far more desirable here.
So I've been hacking all morning and finally got it to work. Well, almost. The compiler still doesn't realize that arithmetic operations can now throw C++ exceptions, and will silently discard the try/catch block around it. It does work when the exception occurs in a function.
void throw_exception()
{
throw std::runtime_error("Division by zero!");
}
__attribute__((noinline))
void try_div0()
{
cout << 1 / 0 << endl;
}
int main()
{
// this class traps a hardware exception (division by zero, in this case) and calls the supplied lambda function.
// uh, no, you probably don't want to see the assembly code behind this...
exception_wrapper div0_exc { 0, [] (exception_frame* frame, bool)
{
if (frame->address.segment != get_cs()) return false; // only handle exceptions that occured in our own code
frame->stack.offset -= 4; // sub <fault esp>, 4;
auto* stack = reinterpret_cast<std::uintptr_t *>(frame->stack.offset); // get <fault esp>
*stack = frame->address.offset; // mov [<fault esp>], <fault address>;
frame->address.offset = reinterpret_cast<std::uintptr_t>(throw_exception); // set return address to throw_exception()
return true; // exception handled!
} };
try
{
// cout << 1 / 0 << endl; // this throws, as expected, but calls std::terminate().
try_div0(); // this exception is caught.
}
catch (std::exception& e)
{
cout << "oops: " << e.what() << endl;
}
}
I realize this is an unusual question... but is there any way I could make this work? Some way to tell gcc that exceptions can occur anywhere?
I'm compiling with djgpp which (I believe) uses DWARF exception handling.
edit: I just found gcc flags -fnon-call-exceptions and -fasynchronous-unwind-tables, which appear to be what I'm looking for. But it still doesn't work...
edit: Now using the previously mentioned gcc flags, it does catch when the exception occurs in between two function calls:
inline void nop() { asm(""); }
// or { cout << flush; } or something. empty function does not work.
int main()
{
/* ... */
try
{
nop();
cout << 1 / 0 << endl;
nop();
}
/* ... */
}
edit: Nested try/catch blocks have the same effect, no exception is caught unless the trapped instruction is preceded by a function call.
inline void nop() { asm(""); }
void try_div(int i)
{
try
{
// this works, catches exception in try_div(0).
nop();
cout << 1 / i << endl;
try_div(i - 1);
// without the first nop(), calls std::terminate()
//cout << 1 / i << endl;
//try_div(i - 1);
// reverse order, also terminates.
//if (i != 0) try_div(i - 1);
//cout << 1 / i << endl;
//nop();
}
catch (std::exception& e)
{
cout << "caught in try_div(" << i << "): " << e.what() << endl;
}
}
int main()
{
/* ... */
try
{
try_div(4);
}
catch (std::exception& e)
{
cout << "caught in main(): " << e.what() << endl;
}
}
edit: I have submitted this as a possible bug in gcc, and reduced my code to a simple test case.
It's been a while, but I finally figured it out... The throwing function needs to be marked as having a signal frame.
[[gnu::no_caller_saved_registers]]
void throw_exception()
{
asm(".cfi_signal_frame");
throw std::runtime_error("Division by zero!");
}

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.