0

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.

corsel
  • 315
  • 2
  • 12
  • As for your problem, without an *actual* [Minimal, Complete, and Verifiable Example](http://stackoverflow.com/help/mcve) it's really hard to say. Are you sure the output you write in the exception handler isn't buffered and haven't been flushed? – Some programmer dude Mar 02 '18 at 13:13
  • 1
    In the shown code, when an exception gets thrown `obj1` gets destroyed, because execution leaves its scope. The fact that a reference to `*this` gets passed to the method where the exception gets thrown is utterly irrelevant. `*this` does not get destroyed when the shown `catch` blocks executes (unless something else explicitly destroyed `*this` from dynamic scope, as part of exception handling, which is undefined behavior). – Sam Varshavchik Mar 02 '18 at 13:15
  • Excuse the mistake in syntax, it's been fixed. I'll also try to post an actual code as soon as possible. My question is a theoretical one, rather than trying to get a working code. – corsel Mar 02 '18 at 13:18
  • You mentioned about threads "From the debugging logs, I can see that related thread gets stuck, although the rest of the threads keep going.". Please model the situation in your example - which thread throws, which catches? – PiotrNycz Mar 02 '18 at 13:25

0 Answers0