31

Just out of curiosity, I'm trying to generate a stack overflow. This code generates a Stack Overflow according to the OP, but when I run it on my machine, it generates a segmentation fault:

#include <iostream>

using namespace std;

int num = 11;
unsigned long long int number = 22;

int  Divisor()
{
    int result;
    result = number%num;

    if (result == 0 && num < 21)
    {
        num+1;
        Divisor();

        if (num == 20 && result == 0)
        {
            return number;
        }
    }

    else if (result != 0)
    {
        number++;
        Divisor();
    }
}

int main ()
{
    Divisor();
    cout << endl << endl;
    system ("PAUSE");
    return 0;
}

Also, according to this post, some examples there should also do the same. Why is it I get segmentation faults instead?

0

6 Answers 6

27

Why is it I get segmentation faults instead?

The segmentation fault, what you're seeing, is a side-effect of the stack overflow. The reason is stack overflow, the result is segmentation fault.

From the wikipedia article for "stack overflow" (emphasis mine)

.... When a program attempts to use more space than is available on the call stack (that is, when it attempts to access memory beyond the call stack's bounds, which is essentially a buffer overflow), the stack is said to overflow, typically resulting in a program crash.

16

A stack overflow can lead to following errors:

  • SIGSEGV (segmentation violation) signal for the process.
  • SIGILL (illegal instruction) signal.
  • SIGBUS an access to an invalid address.

For more read Program Error Signals. Since the behavior is undefined any of the above can come up on different systems/architectures.

13

You are essentially asking: what is the behavior of undefined behavior?

The answer is: undefined behavior is behavior which is not defined. Anything might happen.

Researching why you get a certain undefined behavior on a certain system is most often pointless exercise.

Undefined, unspecified and implementation-defined behavior

In the case of stack overflow, the program might overwrite other variables in RAM, or corrupt the running function's own return address, or attempt to modify memory outside its given address range etc etc. Depending on system, you might get hardware exceptions and various error signals such as SIGSEGV (on POSIX systems), or sudden program crashes, or "program seems to be working fine", or something else.

8
  • Just out of curiosity, can you give chapter and verse for undefined behavior here? I cannot find any mention of stack overflow in my (unofficial) copy of the standard (overflow always seems to mean numeric overflow). Infinite recursion would seem to fall under the general chapter "one cannot expect any implementation to provide unlimited resources", but brandishing Undefined Behavior would seem to require something more specific. Commented May 20, 2015 at 10:16
  • @MarcvanLeeuwen If a behavior isn't covered by the standard, then it is undefined behavior. 3.4.3 undefined behavior behavior, upon use of a nonportable or erroneous program construct or of erroneous data, for which this International Standard imposes no requirements. The C standard need not explicitly list something as undefined behavior to make it so: it is sufficient if the standard does not mention what will happen at all. For example what will happen when calling a recursive function an unlimited amount of times.
    – Lundin
    Commented May 20, 2015 at 11:04
  • 2
    Your argument is not clear. Recursion is not an erroneous program construct, nor does it involve erroneous data. The Standard (I was thinking C++, but on this point C is similar) perfectly decribes how recursive calls are to be handled. I have looked in vain for any mention that attempting a function call might fail due to lack of space on the runtime stack (whereas the possibility of running out of dynamic memory is explicitly catered for, and doesn't in itself cause UB); maybe I looked in the wrong place though. The Standard seems to specify unlimited repetition, as in a loop, rather than UB Commented May 20, 2015 at 11:28
  • 1
    @MattMcNabb How? If this particular stack overflow caused a segmentation fault, it doesn't mean that the next time you get a segmentation fault, it is because of stack overflow. Learning what caused a crash is certainly educational. Already knowing what caused it and examining the consequences of it, less so.
    – Lundin
    Commented May 20, 2015 at 11:50
  • 2
    Yes. "If it's not in the standard I don't care" is an extremely unproductive attitude. The real world exists.
    – Atsby
    Commented May 21, 2015 at 0:32
11

The other answers posted are all correct.

However, if the intent of your question is to understand why you do not see a printed error stating that a stack overflow has occurred, the answer is that some run-time libraries explicitly detect and report stack overflows, while others do not, and simply crash with a segfault.

In particular, it looks like at least some versions of Windows detect Stackoverflows and turn them into exceptions, since the documentation suggests you can handle them.

7

A stack overflow is a cause, a segmentation fault is the result.

On linux and other unix like systems a segmentation fault may be the result, among other things, of a stack overflow. You don't get any specific information that the program encountered a stack overflow.

In the first post you're linking, the person is running the code on Windows which may behave differently, and e.g. detect a stack overflow specifically.

5

I guess you're using a compiler that doesn't have stack checking enabled.

Stack checking is a rather simple mechanism, it kills the program stating that a Stack Overflow Happened as soon as the stack pointer flies past the stack bound. It is often disabled for optimisation purposes, because a program will almost certainly crash on a stack overflow anyway.

Why a segfault? Well, without stack checking enabled, your program doesn't stop after using up the stack, and continues right into unrelated (and quite often protected) memory, which it tries to modify to use as another stack frame for a new function invokation. Madness ensues, and a segfault happens.

1
  • 2
    Usually, the memory just past the end of the stack is deliberately ensured to be unmapped, so that you don't walk into, e.g., malloc()ed data structures.
    – Atsby
    Commented May 21, 2015 at 0:35

Not the answer you're looking for? Browse other questions tagged or ask your own question.