I am trying to call terminate function. [I think this function gets called when another exception arises during stack unwinding]. The same scenario I have written and trying to verify.
I am able to see a call being made to terminate() function but i am not sure why i am geting the Debug Error.
While trying to execute the following code in Visual studio 2008, I am getting an error message dialog box "Debug Error". The output is also being displayed:
Output:
In try block
In constructor of A
In constructor of B
In destructor of B
In destructor of A
Call to my_terminate
Why this "Debug Error" window appears while executing this code? It is expected behavior? How to remove this error?
class E
{
public:
const char* message;
E(const char* arg) : message(arg) { }
};
void my_terminate()
{
cout << "Call to my_terminate" << endl;
};
class A
{
public:
A() { cout << "In constructor of A" << endl; }
~A()
{
cout << "In destructor of A" << endl;
throw E("Exception thrown in ~A()");
}
};
class B
{
public:
B() { cout << "In constructor of B" << endl; }
~B() { cout << "In destructor of B" << endl; }
};
void main()
{
set_terminate(my_terminate);
try
{
cout << "In try block" << endl;
A a;
B b;
throw("Exception thrown in try block of main()");
}
catch (const char* e)
{
cout << "Exception: " << e << endl;
}
catch (...)
{
cout << "Some exception caught in main()" << endl;
}
cout << "Resume execution of main()" << endl;
getch();
}
You are throwing exception from ~A(). Throwing an exception out of a destructor is dangerous. If another exception is already propagating the application will terminate. See https://stackoverflow.com/a/130123/72178 for more detailed description.
Why this "Debug Error" window appears while executing this code?
You are throwing exception in main from try block. This invokes "Stack unwinding" and destructors of A and B are called. When exception is thrown from ~A() application terminates.
It is expected behavior?
Yes, it is defined by Standard.
How to remove this error?
Don't throw from destructors.
Related
At a point in my code, I pass a *this to a method foo(const MyClass& arg). An exception is thrown deep inside this foo, but although a syntactically correct try-catch block exists up the stack, it gets neither handled (a message should have been emitted in that case), nor the process crashes. From the debugging logs, I can see that related thread gets stuck, although the rest of the threads keep going.
I've been through stack unwinding documentation, and somewhere I've seen that arguments to functions are also considered to be auto variables, and get destroyed during the unwinding process. That brings me to the question: what happens when I pass a const reference of this (inside which there is a corresponding catch block) to a method where an exception is thrown? Is it possible that the ref gets the caller object destroyed, and catch block is now unreachable even though stack unwinding has begun already?
Let me add some pseudoish-code:
void MyClass0::someFunc(void)
{
try
{
MyClass1 obj1;
obj1.someOtherFunc(*this);
// Some other stuff
}
catch (MyException&)
{
std::cout << "Handling exception...";
// Whatever... This message is not emitted.
}
}
void MyClass1::someOtherFunc(const MyClass0& argObj0)
{
// Some functions that eventually throw an unhandled MyException
}
Thanks in advance...
EDIT:
OK, trying to generate an executable code for reference, I believe I pretty much answered my own question.
Here's the code:
#include "sandbox.h"
#include <iostream>
MyClass0::MyClass0(void)
{
std::cout << "\nConstructing MyClass0";
}
MyClass0::~MyClass0(void)
{
std::cout << "\nDestructing MyClass0";
}
void MyClass0::trustIssues(void)
{
std::cout << "\nEntering " << __FUNCTION__;
try
{
MyClass1 myClass1;
myClass1.unwaryFunction(*this);
}
catch (MyException& exc)
{
std::cout << "\nException caught in " << __FUNCTION__;
std::cout << "\nLeaving " << __FUNCTION__ << " from inside catch block.";
return;
}
std::cout << "\nLeaving " << __FUNCTION__;
}
MyClass1::MyClass1(void)
{
std::cout << "\nConstructing MyClass1";
}
MyClass1::~MyClass1(void)
{
std::cout << "\nDestructing MyClass1";
}
void MyClass1::unwaryFunction(MyClass0& argClass0)
{
std::cout << "\nEntering " << __FUNCTION__;
suicidalFunction();
std::cout << "\nLeaving " << __FUNCTION__;
}
void suicidalFunction(void)
{
std::cout << "\nEntering " << __FUNCTION__;
MyException myException;
throw myException;
std::cout << "\nLeaving " << __FUNCTION__;
}
int main(int argc, char* argv[])
{
MyClass0 myClass0;
myClass0.trustIssues();
return 0;
}
The output has been:
Constructing MyClass0
Entering MyClass0::trustIssues
Constructing MyClass1
Entering MyClass1::unwaryFunction
Entering suicidalFunction
Destructing MyClass1
Exception caught in MyClass0::trustIssues
Leaving MyClass0::trustIssues from inside catch block.
This implies that the *this argument does not get destroyed on stack unwinding of unwaryFunction. I probably have some other bug in the actual code (as the message analogous to "Exception caught in..." does not get printed). I'll keep this question for future reference. Thanks for your concern anyway.
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!");
}
IN the below code snippet why is that if I include the catch statement with "exception base class I get a app crash" (attached the image of teh crash).
But if I use
"const char* msg"
in catch() it works fine.
WHy is it that the exception base class is causing teh app crash ?
double division(int a, int b)
{
if (b == 0)
{
throw "Division by zero condition!";
}
return (a / b);
}
main()
{
int x = 50;
int y = 0;
double z = 0;
try {
z = division(x, y);
cout << "after division func" << endl;
cout << z << endl;
}
catch (const char* msg) { // WORKS FINE
//catch (exception& err) { // CAUSES the APP to crash![enter image description here][1]
cout << "INside catch for divide by 0" << endl;
}
Here you are throwing a string literal:
throw "Division by zero condition!";
Which can be caught with the following:
catch (const char* msg)
However this exception does not derive from the class std::exception. If you want one which is and can provide an error message then use std::runtime_error.
throw std::runtime_error("Division by zero condition!");
...
catch (std::exception& err)
Division by zero condition is not derived by std::exception
one workaround you can do is to define catch all statement in you code
try {
z = division(x, y);
cout << "after division func" << endl;
cout << z << endl;
}
catch (exception& err) { // CAUSES the APP to crash![enter image description here][1]
cout << "INside catch for divide by 0" << endl;
}
catch(...) //include this in your code
{
cout<<"other exception occured";
}
See here http://ideone.com/TLukAp
I'm using my own Exception class that inherits from std::exception. I'm pretty sure the class is okay since it has always worked up until now. I'm trying to throw an error from a constructor:
DataBase::DataBase()
: _result(NULL)
{
mysql_init(&_mysql);
mysql_options(&_mysql,MYSQL_READ_DEFAULT_GROUP,"option");
if(!mysql_real_connect(&_mysql,"localhost","root","","keylogger",0,NULL,0))
throw Exception(__LINE__ - 1, __FILE__, __FUNCTION__, "Can't connect to DB");
}
Here is my try/catch block :
int main(int, char **)
{
//[...]
Server server([...]); // DB is a private member in Server
try
{
server.fdMonitor();
}
catch (Exception &e)
{
std::cout << "Error: in " << e.file() << ", " << "function " << e.function()
<< "(line " << e.line() << ") : " << std::endl
<< "\t" << e.what() << std::endl;
}
return (1);
}
The problem is that the Exception thrown from my DB constructor isn't caught. Here's the abort message:
terminate called after throwing an instance of 'Exception'
what(): Can't connect to DB
Aborted
Any ideas?
Thanks in advance.
From your description, it sounds like the DataBase constructor is called from the Server constructor.
So, you need to move that line into the try block :
try
{
Server server([...]); // DB is a private member in Server
server.fdMonitor();
}
catch (Exception &e)
{
// ...
}
The problem is that the place which throws (construction of server) is not within the try block.
I have a class whose constructor will throw an exception. I also have a catch block to handle that exception. But still, I see that the exception is propagated back to the caller even though it is handled. I know, there should be an exception to inform the caller that construction failed. But in this case how does it (re-throw) happen?
class Test
{
public:
Test()
try
{
std::cout << "in child constructor" << std::endl;
throw 3.2;
}
catch(int &e)
{
std::cout << "in int catch: " << e << std::endl;
}
catch (double &e)
{
std::cout << "in double catch: " << e << std::endl;
}
};
int main (void)
{
try
{
Test obj;
}
catch (int &e)
{
std::cout << "in main int catch: " << e << std::endl;
}
catch (double &e)
{
std::cout << "in main double catch: " << e << std::endl;
}
return 0;
}
The output I got is
in child constructor
in double catch: 3.2
in main double catch: 3.2
This is correct according to standard. Section 15.3, point 15 of n3337.pdf reads:
The currently handled exception is rethrown if control reaches the end of a handler of the function-try-block of a constructor or destructor. Otherwise, a function returns when control reaches the end of a handler for the function-try-block (6.6.3). Flowing off the end of a function-try-block is equivalent to a return with no value; this results in undefined behavior in a value-returning function (6.6.3).
You can fully catch and prevent an exception from propagating inside constructor/destructor body. You cannot however catch the exceptions thrown from base class/member constructors/destructors this way.