Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Catching "Stack Overflow" exceptions in recursive C++ functions

Is it possible to catch a stack overflow exception in a recursive C++ function? If so, how?

so what will happen in this case

void doWork()
{

     try() {

     doWork();    
     }


     catch( ... )  {

     doWork();    
     }
}  

I am not looking for an answer to specific OS. Just in general

like image 650
omar Avatar asked Oct 16 '09 15:10

omar


People also ask

How does recursion c prevent stack overflow?

In order to prevent stack overflow bugs, you must have a base case where the function stops make new recursive calls. If there is no base case then the function calls will never stop and eventually a stack overflow will occur. Here is an example of a recursive function with a base case.

Can recursive functions cause stack overflow?

The most-common cause of stack overflow is excessively deep or infinite recursion, in which a function calls itself so many times that the space needed to store the variables and information associated with each call is more than can fit on the stack.

Can you catch a StackOverflowException?

NET Framework 2.0, you can't catch a StackOverflowException object with a try / catch block, and the corresponding process is terminated by default. Consequently, you should write your code to detect and prevent a stack overflow.

Can you catch a StackOverflowException Java?

StackOverflowError is an error which Java doesn't allow to catch, for instance, stack running out of space, as it's one of the most common runtime errors one can encounter.


2 Answers

It's not an exception per se, but if you just want to be able to limit your stack usage to a fixed amount, you could do something like this:

#include <stdio.h>

// These will be set at the top of main()
static char * _topOfStack;
static int _maxAllowedStackUsage;

int GetCurrentStackSize()
{
   char localVar;
   int curStackSize = (&localVar)-_topOfStack;
   if (curStackSize < 0) curStackSize = -curStackSize;  // in case the stack is growing down
   return curStackSize;
}

void MyRecursiveFunction()
{
   int curStackSize = GetCurrentStackSize();
   printf("MyRecursiveFunction:  curStackSize=%i\n", curStackSize);

   if (curStackSize < _maxAllowedStackUsage) MyRecursiveFunction();
   else
   {
      printf("    Can't recurse any more, the stack is too big!\n");
   }
}

int main(int, char **)
{
   char topOfStack;
   _topOfStack = &topOfStack;
   _maxAllowedStackUsage = 4096;  // or whatever amount you feel comfortable allowing

   MyRecursiveFunction();
   return 0;
}
like image 58
Jeremy Friesner Avatar answered Nov 16 '22 18:11

Jeremy Friesner


There isn't a portable way. However, there are a few nonportable solutions.

First, as others have mentioned, Windows provides a nonstandard __try and __except framework called Structured Exeption Handling (your specific answer is in the Knowledge Base).

Second, alloca -- if implemented correctly -- can tell you if the stack is about to overflow:

bool probe_stack(size_t needed_stack_frame_size)
{
    return NULL != alloca(needed_stack_frame_size);
};

I like this approach, because at the end of probe_stack, the memory alloca allocated is released and available for your use. Unfortunately only a few operating systems implement alloca correctly. alloca never returns NULL on most operating systems, letting you discover that the stack has overflown with a spectacular crash.

Third, UNIX-like systems often have a header called ucontext.h with functions to set the size of the stack (or, actually, to chain several stacks together). You can keep track of where you are on the stack, and determine if you're about to overflow. Windows comes with similar abilities a la CreateFiber.


As of Windows 8, Windows has a function specifically for this (GetCurrentThreadStackLimits)

like image 30
Max Lybbert Avatar answered Nov 16 '22 18:11

Max Lybbert