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.