1

For example, this code will throw Stack Overflow because of infinite recursion which will lead to the program crash. Is there a way to handle this exception and avoid the crash and move on to the next instruction execution?

#include <iostream>
#include <exception>

template <typename T>
T sum(T firstValue, T secondValue)
{
        try{
                return firstValue + secondValue;
        }

        catch(const std::exception &e)
        {
                std::cerr << "Caught exception: " << e.what() << '\n';
        }
}

void causeStackOverflow() {
    causeStackOverflow();
}

int main() {

        std::cout << "Sum of 3 & 4 is: " << sum(3, 4) << '\n';

    try {
        causeStackOverflow();
    }

    catch (const std::exception& e) {
        std::cerr << "Caught exception: " << e.what() << '\n'; // If anything can be done here so program can recover and next line can execute?
    }

        std::cout << "Sum of 1 & 2 is: " << sum(1, 2) << '\n';

    return 0;
}

There must be some way which can be used here to do this. Another question would be if it should be done even if it's possible?

Is there any way which can predict with some probability that Stack Overflow is going to happen? So we can take some action to avoid that?

StewieGGriffin
  • 349
  • 1
  • 4
  • 14
  • Definitely not in standard C++ and even if you use the other options (SEH) I don't think you can catch that one as it's considered an unrecoverable programming error. You should never be programming for infinite recursion in C++, at least not until tail recursion is implemented in the standard. – Mgetz Jan 19 '23 at 13:48
  • I was thinking that it its doable than I will try to implement somethings in my project so it avoids crash and recovers and continues. – StewieGGriffin Jan 19 '23 at 14:16
  • 2
    Yes, actually, on Windows there is. But I'm not sure if it comes with bad side effects. You have to catch `EXCEPTION_STACK_OVERFLOW` error with SEH (__try/__except) and then call _resetstkoflw. – user253751 Jan 19 '23 at 14:28
  • 2
    @StewieGGriffin something being doable doesn't mean you _should_ do it. A stack overflow leaves the application with a corrupted stack and thus undefined behavior. The best solution is to fix the stack overflow, not to just try to work around it. – Mgetz Jan 19 '23 at 14:34
  • @StewieGGriffin "My car has two blown out tires. I want to keep driving the car." -- Is this what you are basically asking? – PaulMcKenzie Jan 19 '23 at 14:45
  • 2
    My rule: *the maximum recursion level for a recursive function shall be **O(log n)***. Having a **O(n)** level like this implementation is asking for trouble: it will quickly crash with (not so) big `n`. And this type of recursive function can be very easily converted to a loop, that is easier to understand, easier to debug, safer and faster. – prapin Jan 19 '23 at 15:39
  • 1
    A well behaved function should throw an exception _before_ the error occurs. For example, by examining its parameters for values that will cause an error.. – Michaël Roy Jan 19 '23 at 17:15
  • @PaulMcKenzie - No, I am more into finding out before that my tires are going to be blown and if there are some measures by which I can monitor my tires health and take some action before they blow. – StewieGGriffin Jan 20 '23 at 08:43
  • 1
    @StewieGGriffin Once the exception is thrown the tires are blown. Any action would have to be before the exception. Which is what other comments were suggesting. – Joris Timmermans Jan 20 '23 at 09:07
  • Stack overflow limitations and their handling is a platform-specific and compiler-specific implementation detail. The behaviour is not specified by the standard. The C++ standards only specify that compilers should document their limitations. See [What does the C++ standard say about stack overflow?](https://stackoverflow.com/questions/6589946/what-does-the-c-standard-say-about-stack-overflow) – Wyck Jan 23 '23 at 03:16
  • Did the answer below work for you? – Minxin Yu - MSFT Jan 25 '23 at 02:44

2 Answers2

1

On Windows, with Microsoft Visual C++, you can handle a stack overflow using Structured Exception Handling (SEH) like this:

void causeStackOverflow() {
    causeStackOverflow();
}

// Filter for the stack overflow exception.
// This function traps the stack overflow exception, but passes
// all other exceptions through.
int stack_overflow_exception_filter(int exception_code)
{
   if (exception_code == EXCEPTION_STACK_OVERFLOW)
   {
       // Do not call _resetstkoflw here, because
       // at this point, the stack isn't yet unwound.
       // Instead, signal that the handler (the __except block)
       // is to be executed.
       return EXCEPTION_EXECUTE_HANDLER;
   }
   else
       return EXCEPTION_CONTINUE_SEARCH;
}

int main() {
    // Demonstrate handling a stack overflow 3 times.
    for (int i = 0; i < 3; ++i) {
        __try {
            causeStackOverflow();
        }
        __except (stack_overflow_exception_filter(GetExceptionCode())) {
            std::cout << "Handled!\n";
            if (!_resetstkoflw()) {
                // Failed to reset the stack.  Emergency exit.
                exit(-1);
            }
        }
    }
}

Important: A stack overflow exception damages the guard page that will catch any subsequent stack overflow exceptions. You have to put these guard pages back by calling _resetstkoflw if you want to be able to recover from another future stack overflow exception on that same thread. I strongly suggest reading the entire remarks section in the documentation.

The _resetstkoflw function recovers from a stack overflow condition, allowing a program to continue instead of failing with a fatal exception error. If the _resetstkoflw function isn't called, there are no guard pages after the previous exception. The next time that there's a stack overflow, there are no exceptions at all and the process terminates without warning.

...

Wyck
  • 10,311
  • 6
  • 39
  • 60
0

You could refer to the MSDN document to debug stack overflow.

Use the !analyze command to check that we have indeed have a problem with our loop.

dt _TEB can be used to display information.

It is difficult to catch exception because the OS will kill the process. For your reference: C++: Getting exception from stack overflow?.

Minxin Yu - MSFT
  • 2,234
  • 1
  • 3
  • 14