144
votes
\$\begingroup\$

As a programmer you certainly know the error of a stack overflow due to an obvious recursion. But there are certainly many weird and unusual ways to get your favourite language to spit that error out.

Objectives:

  1. Must cause a stack overflow which is clearly visible on the error output.
  2. Not allowed to use an obvious recursion.

Examples of invalid programs:

// Invalid, direct obvious recursion.
methodA(){ methodA(); }
// Invalid, indirect, but obvious recursion.
methodA(){ methodB(); }
methodB(){ methodA(); }

The most creative ways are the best as this a . I.e, avoid boring obvious answers like this:

throw new StackOverflowError(); // Valid, but very boring and downvote-deserving.

Even though I accepted an answer now, adding more answers is still okay :)

\$\endgroup\$
19
  • 14
    \$\begingroup\$ I tend to produce by navigating to stackoverflow.com, though I have been known to query 'stack overflow' on my search engine of choice. \$\endgroup\$
    – OJFord
    Commented Feb 17, 2014 at 13:19
  • 21
    \$\begingroup\$ Use Internet Explorer. A sure way to catch one :) \$\endgroup\$
    – asgoth
    Commented Feb 18, 2014 at 17:48
  • 64
    \$\begingroup\$ The weirdest way to produce a stack overflow is to post a popularity-contest on codegolf.stackexchange.com asking for people to post the weirdest way to produce a stack overflow. The responders, in testing their solutions to the question, will produce a stack overflow. I haven't tested it though, so I can't be sure it works (which is why I didn't post it as an answer). \$\endgroup\$ Commented Feb 18, 2014 at 20:32
  • 3
    \$\begingroup\$ I'm partial to this method: joelonsoftware.com/items/2008/09/15.html \$\endgroup\$
    – robert
    Commented Feb 19, 2014 at 13:10
  • 11
    \$\begingroup\$ Drive a Toyota (Hey, wait a minute, my car is a Toyota...) \$\endgroup\$
    – r3mainer
    Commented Feb 22, 2014 at 1:08

116 Answers 116

224
votes
\$\begingroup\$

Python

import sys
sys.setrecursionlimit(1)

This will cause the interpreter to fail immediately:

$ cat test.py
import sys
sys.setrecursionlimit(1)
$ python test.py
Exception RuntimeError: 'maximum recursion depth exceeded' in <function _remove at 0x10e947b18> ignored
Exception RuntimeError: 'maximum recursion depth exceeded' in <function _remove at 0x10e8f6050> ignored
$ 

Instead of using recursion, it just shrinks the stack so it will overflow immediately.

\$\endgroup\$
12
  • 12
    \$\begingroup\$ Cute, but not quite what the original question was aiming for in my opinion. \$\endgroup\$
    – Etheryte
    Commented Feb 17, 2014 at 22:01
  • 12
    \$\begingroup\$ @Nit I don't see the problem. What about this solution is unsatisfactory? \$\endgroup\$
    – SimonT
    Commented Feb 18, 2014 at 6:08
  • 17
    \$\begingroup\$ @masterX244 Yes, the whole point of the question is "don't do it the usual way". \$\endgroup\$
    – Plutor
    Commented Feb 18, 2014 at 12:58
  • 24
    \$\begingroup\$ @Plutor do you usually set up a StackOverFlow on purpose ? \$\endgroup\$
    – Kiwy
    Commented Feb 18, 2014 at 13:54
  • 15
    \$\begingroup\$ This was only mildly clever the first time it was posted. \$\endgroup\$
    – primo
    Commented Feb 20, 2014 at 10:55
190
votes
\$\begingroup\$

Python

import webbrowser
webbrowser.open("http://stackoverflow.com/")
\$\endgroup\$
17
  • 7
    \$\begingroup\$ Fantastic. Nice and elegant. \$\endgroup\$ Commented Feb 18, 2014 at 16:08
  • 103
    \$\begingroup\$ Much literal. Very answer. \$\endgroup\$ Commented Feb 18, 2014 at 20:58
  • 47
    \$\begingroup\$ Well, this shows a Stack Overflow, but to produce one, this only works if it's Jeff Atwood or Joel Spolsky executing it. \$\endgroup\$ Commented Feb 20, 2014 at 0:22
  • 10
    \$\begingroup\$ @TimSeguine Wow. \$\endgroup\$ Commented Feb 20, 2014 at 4:15
  • 9
    \$\begingroup\$ Not an answer as it's not in the error output. \$\endgroup\$ Commented Feb 20, 2014 at 12:40
131
votes
\$\begingroup\$

C / Linux 32bit

void g(void *p){
        void *a[1];
        a[2]=p-5;
}
void f(){
        void *a[1];
        g(a[2]);
}
main(){
        f();
        return 0;
}

Works by overwriting the return address, So g returns to the point in main before calling f. Will work for any platform where return addresses are on the stack, but may require tweaks.

Of course, writing outside of an array is undefined behavior, and you have no guarantee that it will cause a stack overflow rather than, say, paint your mustache blue. Details of platform, compiler and compilation flags may make a big difference.

\$\endgroup\$
14
  • 1
    \$\begingroup\$ Wouldn't this produce a segfault? \$\endgroup\$
    – 11684
    Commented Feb 17, 2014 at 14:01
  • 4
    \$\begingroup\$ +1 for the weird stack manipulation and absolutely no recursion! \$\endgroup\$
    – RSFalcon7
    Commented Feb 17, 2014 at 14:39
  • 6
    \$\begingroup\$ @11684, It's undefined behavior, so in general it could crash. On 32bit Linux (that I tested on), it writes outside the array, overwriting the return address, and doesn't crash until the stack overflows. \$\endgroup\$
    – ugoren
    Commented Feb 17, 2014 at 14:45
  • 46
    \$\begingroup\$ "Paint your moustache blue" -> That line had me. \$\endgroup\$ Commented Feb 17, 2014 at 21:22
  • 2
    \$\begingroup\$ Wow. This is fantastically obfuscated. \$\endgroup\$ Commented Feb 17, 2014 at 23:59
106
votes
\$\begingroup\$

JavaScript / DOM

with (document.body) {
    addEventListener('DOMSubtreeModified', function() {
        appendChild(firstChild);
    }, false);

    title = 'Kill me!';
}

If you want to kill your browser try that out in the console.

\$\endgroup\$
7
  • 53
    \$\begingroup\$ I'm sure you deserve more +1 votes, but sadly people tried this before voting.... lol \$\endgroup\$
    – Reactgular
    Commented Feb 18, 2014 at 23:06
  • 5
    \$\begingroup\$ Well, that was effective. I couldn't even get my task manager open to kill it. \$\endgroup\$
    – primo
    Commented Feb 20, 2014 at 14:54
  • 1
    \$\begingroup\$ Use Chrome, close tab. Problem solved. \$\endgroup\$
    – Cole Tobin
    Commented Feb 21, 2014 at 4:19
  • 1
    \$\begingroup\$ with (document.body) { addEventListener('DOMSubtreeModified', function() { appendChild(firstChild); }, false); title = 'Kill me!'; } 15:43:43.642 TypeError: can't convert undefined to object \$\endgroup\$ Commented Feb 21, 2014 at 20:44
  • 1
    \$\begingroup\$ Damn My Firefox was hanged \$\endgroup\$
    – Farhad
    Commented Feb 24, 2014 at 10:14
91
votes
\$\begingroup\$

Java

Saw something like this somewhere around here:

Edit: Found where I saw it: Joe K's answer to Shortest program that throws StackOverflow Error

public class A {
    String val;
    public String toString() {
        return val + this;
    }

    public static void main(String[] args) {
        System.out.println(new A());
    }
}

That can confuse some Java beginners. It simply hides the recursive call. val + this becomes val + this.toString() because val is a String.

See it run here: http://ideone.com/Z0sXiD

\$\endgroup\$
7
  • 30
    \$\begingroup\$ Actually, it does new StringBuilder().append(val).append("").append(this).toString(), and the last append calls String.valueOf(...), which in turn calls toString. This makes your Stack trace a bit varied (three methods in there). \$\endgroup\$ Commented Feb 17, 2014 at 14:13
  • 2
    \$\begingroup\$ @PaŭloEbermann Yeah, that is correct. However, it is much easier to say that it becomes "" + this.toString(). \$\endgroup\$
    – Justin
    Commented Feb 18, 2014 at 3:35
  • 2
    \$\begingroup\$ I think the + "" + might tip people off, as it looks useless at first glance. String val; and return val + this; might be marginally sneakier \$\endgroup\$
    – Cruncher
    Commented Feb 18, 2014 at 21:45
  • \$\begingroup\$ @Cruncher not at all. If you are a Java coder, you would know that the easy way of concatenating an int to a string during ""-String construction is with the + "" \$\endgroup\$
    – Justin
    Commented Feb 19, 2014 at 1:20
  • 5
    \$\begingroup\$ In a real world application I would prefer to avoid infinite recursion and stack overflow errors \$\endgroup\$ Commented Feb 23, 2014 at 15:32
77
votes
\$\begingroup\$

C

Quite easy:

int main()
{
    int large[10000000] = {0};
    return 0;
}
\$\endgroup\$
14
  • 10
    \$\begingroup\$ +1 for non obvious! Despite it is very system dependent (an ulimit -s unlimited in the shell solves this in linux) \$\endgroup\$
    – RSFalcon7
    Commented Feb 17, 2014 at 14:57
  • 4
    \$\begingroup\$ @RSFalcon7, thanks for the +1, but to me this was actually the most obvious!! \$\endgroup\$
    – Shahbaz
    Commented Feb 17, 2014 at 18:39
  • 14
    \$\begingroup\$ @Cruncher: It doesn't result in recursion. The problem given was to blow the stack. On many operating systems the stack is of fixed size, and far smaller than ten million ints, so this blows the stack. \$\endgroup\$ Commented Feb 18, 2014 at 17:58
  • 2
    \$\begingroup\$ @HannoBinder, In Linux where I tested, you don't get a stack overflow error. You get a segmentation fault, since overflowing the stack results in access to unowned segments. I'm not sure if stack overflow error even exists in Linux, since an infinite recursive function call also gives out a segmentation fault. \$\endgroup\$
    – Shahbaz
    Commented Feb 19, 2014 at 13:33
  • 3
    \$\begingroup\$ ~0u is a pretty large number in C. \$\endgroup\$
    – Vortico
    Commented Feb 23, 2014 at 20:20
63
votes
\$\begingroup\$

Non-recursive stack overflow in C

Calling convention mismatch.

typedef void __stdcall (* ptr) (int);

void __cdecl hello (int x) { }

void main () {
  ptr goodbye = (ptr)&hello;
  while (1) 
    goodbye(0);
}

Compile with gcc -O0.

__cdecl functions expect the caller to clean up the stack, and __stdcall expects the callee to do it, so by calling through the typecast function pointer, the cleanup is never done -- main pushes the parameter onto the stack for each call but nothing pops it and ultimately the stack fills.

\$\endgroup\$
1
  • 2
    \$\begingroup\$ nice way of spamming the stack :P \$\endgroup\$
    – masterX244
    Commented Feb 18, 2014 at 8:23
62
votes
\$\begingroup\$

I was frustrated by the fact that java 7 and java 8 are immune to my evil code in my previous answer. So I decided that a patch for that was necessary.

Success! I made printStackTrace() throw a StackOverflowError. printStackTrace() is commonly used for debugging and logging and no one reasonably suspects that it could be dangerous. It is not hard to see that this code could be abused to create some serious security issues:

public class StillMoreEvilThanMyPreviousOne {
    public static void main(String[] args) {
        try {
            evilMethod();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void evilMethod() throws Exception {
        throw new EvilException();
    }

    public static class EvilException extends Exception {
        @Override
        public Throwable getCause() {
            return new EvilException();
        }
    }
}

Some people may think that this is an obvious recursion. It is not. The EvilException constructor does not calls the getCause() method, so that exception can actually be thrown safely after all. Calling the getCause() method will not result in a StackOverflowError either. The recursion is inside JDK's normally-unsuspected printStackTrace() behaviour and whatever 3rd party library for debugging and logging that are used to inspect the exception. Further, it is likely that the place where the exception is thrown is very far from the place where it is handled.

Anyway, here is a code that does throw a StackOverflowError and contains no recursive method calls after all. The StackOverflowError happens outside the main method, in JDK's UncaughtExceptionHandler:

public class StillMoreEvilThanMyPreviousOneVersion2 {
    public static void main(String[] args) {
        evilMethod();
    }

    private static void evilMethod() {
        throw new EvilException();
    }

    public static class EvilException extends RuntimeException {
        @Override
        public Throwable getCause() {
            return new EvilException();
        }
    }
}
Exception: java.lang.StackOverflowError thrown from the UncaughtExceptionHandler in thread "main"
\$\endgroup\$
14
  • 2
    \$\begingroup\$ :D and now with a cross java version stackoverflow compliant method. Evil bastard ! :D \$\endgroup\$
    – Kiwy
    Commented Feb 17, 2014 at 13:32
  • 9
    \$\begingroup\$ I am inclined to consider the recursion in this case obvious. \$\endgroup\$
    – Taemyr
    Commented Feb 17, 2014 at 14:34
  • 1
    \$\begingroup\$ @BlacklightShining Calling the getCause() method does not results in StackOverflowError. It is relying in the fact that there is a JDK's code which is recursively calling the getCause() method. \$\endgroup\$ Commented Feb 17, 2014 at 16:17
  • 2
    \$\begingroup\$ I thought you could simplify this by changing the body of getCause to just return this; but apparently Java is too clever for that. It notices that it is a "CIRCULAR REFERENCE". \$\endgroup\$ Commented Feb 23, 2014 at 3:56
  • 1
    \$\begingroup\$ I did not get a StackOverflowError because the OpenBSD 5.5 package of jdk-1.7.0.21p2v0 has a bug. It doesn't throw StackOverflowError. It hits SIGSEGV and dumps core. \$\endgroup\$
    – kernigh
    Commented May 12, 2014 at 23:00
60
votes
\$\begingroup\$

JavaScript

window.toString = String.toLocaleString;
+this;
\$\endgroup\$
6
  • 5
    \$\begingroup\$ This one is underappreciated. \$\endgroup\$
    – Ry-
    Commented Feb 20, 2014 at 2:11
  • 1
    \$\begingroup\$ What does +this do? \$\endgroup\$ Commented Feb 20, 2014 at 19:24
  • 8
    \$\begingroup\$ Unary + invokes the ToNumber abstract operation. That uses the ToPrimitive operation with a hint type of number. ToPrimitive on an Object uses the [[DefaultValue]] internal method, which when passed a number hint, first checks to see if the valueOf() method exists and returns a primitive. window.valueOf() returns an object, so instead [[DefaultValue]] returns the result of calling toString(). The first thing window.toString does (now that it's toLocaleString) is invoke toString on 'this'. Repeat. \$\endgroup\$ Commented Feb 20, 2014 at 19:40
  • 3
    \$\begingroup\$ If Chrome throws an error, 'Too much recursion', then it does work on Chrome, right? The stack overflows, and that's how Chrome delivers a stack overflow exception. \$\endgroup\$ Commented Feb 23, 2014 at 4:02
  • 4
    \$\begingroup\$ You should use +{toString:"".toLocaleString} :-) \$\endgroup\$
    – Bergi
    Commented Feb 24, 2014 at 4:26
57
votes
\$\begingroup\$

Linux x86 NASM Assembly

section .data
    helloStr:     db 'Hello world!',10 ; Define our string
    helloStrLen:  equ $-helloStr       ; Define the length of our string

section .text
    global _start

    doExit:
        mov eax,1 ; Exit is syscall 1
        mov ebx,0 ; Exit status for success
        int 80h   ; Execute syscall

    printHello:
        mov eax,4           ; Write syscall is No. 4
        mov ebx,1           ; File descriptor 1, stdout
        mov ecx,helloStr    ; Our hello string
        mov edx,helloStrLen ; The length of our hello string
        int 80h             ; execute the syscall

    _start:
        call printHello ; Print "Hello World!" once
        call doExit     ; Exit afterwards

Spoiler:

Forgetting to return from printHello, so we jump right into _start again.

\$\endgroup\$
7
  • 78
    \$\begingroup\$ In assembly, nothing is obvious. \$\endgroup\$
    – 11684
    Commented Feb 17, 2014 at 14:00
  • 21
    \$\begingroup\$ @11684: I find the opposite to be true: in assembly, everything is obvious because nobody can use abstractions to hide what their code is really doing. \$\endgroup\$ Commented Feb 17, 2014 at 20:06
  • 3
    \$\begingroup\$ This is brilliant for its simplicity and elegance. \$\endgroup\$ Commented Feb 17, 2014 at 20:13
  • 11
    \$\begingroup\$ @MasonWheeler: I prefer to say that everything is visible instead of obvious... For a nice way to see the difference between visible and obvious, I love to refer to underhanded.xcott.com \$\endgroup\$ Commented Feb 18, 2014 at 10:13
  • 2
    \$\begingroup\$ I remember my frequent mistakes of forgetting ret \$\endgroup\$
    – Ruslan
    Commented Feb 19, 2014 at 8:54
48
votes
\$\begingroup\$

C++ at compile time

template <unsigned N>
struct S : S<N-1> {};

template <>
struct S<0> {};

template
struct S<-1>;
$ g++ -c test.cc -ftemplate-depth=40000
g++: internal compiler error: Segmentation fault (program cc1plus)
Please submit a full bug report,
with preprocessed source if appropriate.
See  for instructions.

There is no recursion this source file, not one of the classes has itself as a base class, not even indirectly. (In C++, in a template class like this, S<1> and S<2> are completely distinct classes.) The segmentation fault is due to stack overflow after recursion in the compiler.

\$\endgroup\$
9
  • 7
    \$\begingroup\$ I confess I would have called this an obvious recursion in your metaprogram. \$\endgroup\$
    – user16488
    Commented Feb 17, 2014 at 16:59
  • 2
    \$\begingroup\$ GCC detects recursion and stops gracefully this side (4.8 and above seem to be fine) \$\endgroup\$
    – Alec Teal
    Commented Feb 17, 2014 at 18:39
  • 2
    \$\begingroup\$ template <typename T> auto foo(T t) -> decltype(foo(t)); decltype(foo(0)) x; is a bit shorter. \$\endgroup\$
    – Casey
    Commented Feb 17, 2014 at 21:13
  • 2
    \$\begingroup\$ @hvd It seems to be exploiting a bug in GCC. clang catches the erroneous usage - which I assume you are already aware of - but it makes my GCC spew almost 2 megabytes of error messages. \$\endgroup\$
    – Casey
    Commented Feb 17, 2014 at 22:35
  • 4
    \$\begingroup\$ +1 for meta stack overflow :p \$\endgroup\$
    – Aschratt
    Commented Feb 21, 2014 at 10:12
45
votes
\$\begingroup\$

Bash (Danger Alert)

while true
do 
  mkdir x
  cd x
done

Strictly speaking, that will not directly stack overflow, but generates what may be labelled as "a persistent stack-over-flow generating situation": when you run this until your disk is full, and want to remove the mess with "rm -rf x", that one is hit.

It does not happen on all systems, though. Some are more robust than others.

Big danger WARNING:

some systems handle this very badly and you may have a very hard time cleaning up (because "rm -rf" itself will run into a recusion problem). You may have to write a similar script to cleanup.

Better try this in a scratch VM if not sure.

PS: the same applies, of course, if programmed or done in a batch script.
PPS: it may be interresting to get a comment from you, how your particular system behaves...

\$\endgroup\$
9
  • \$\begingroup\$ as I wrote: on many systems, rm -rf tries to go down and is hit by one (maybe no longer, these days, with 64bit address space - but on smaller machines with a smaller stack, it may). Of course, there may also be "rm"-implementations around, which do it differently... \$\endgroup\$
    – blabla999
    Commented Feb 17, 2014 at 12:48
  • 2
    \$\begingroup\$ Seems to me something like while cd x; do :; done; cd ..; while rmdir x; cd ..; done; should take care of this. \$\endgroup\$ Commented Feb 17, 2014 at 15:29
  • \$\begingroup\$ You are absolutely right (that's what I meant with "similar script for cleanup"). However, once your disk (or quota) is full, you may even have a hard time logging in afterwards, as some systems used to deal with that situation badly. You'll have to get in as root and do the script (which is easy on those PCs of today, but was often hard in ancient times, when computers where used by more than one user). \$\endgroup\$
    – blabla999
    Commented Feb 18, 2014 at 10:57
  • \$\begingroup\$ funny, this gets more votes than the Smalltalk magic below (never thought that!) \$\endgroup\$
    – blabla999
    Commented Feb 18, 2014 at 11:55
  • \$\begingroup\$ someone tried this on Windows? \$\endgroup\$ Commented Feb 21, 2014 at 7:52
43
votes
\$\begingroup\$

Java

A nice one from Java Puzzlers. What does it print?

public class Reluctant {
    private Reluctant internalInstance = new Reluctant();

    public Reluctant() throws Exception {
        throw new Exception("I'm not coming out");
    }

    public static void main(String[] args) {
        try {
            Reluctant b = new Reluctant();
            System.out.println("Surprise!");
        } catch (Exception ex) {
            System.out.println("I told you so");
        }
    }
}

It actually fails with a StackOverflowError.

The exception in the constructor is just a red herring. This is what the book has to say about it:

When you invoke a constructor, the instance variable initializers run before the body of the constructor. In this case, the initializer for the variable internalInstance invokes the constructor recursively. That constructor, in turn, initializes its own internalInstance field by invoking the Reluctant constructor again and so on, ad infinitum. These recursive invocations cause a StackOverflowError before the constructor body ever gets a chance to execute. Because StackOverflowError is a subtype of Error rather than Exception, the catch clause in main doesn't catch it.

\$\endgroup\$
0
41
votes
\$\begingroup\$

LaTeX

\end\end

The input stack overflows because \end repeatedly expands itself in an infinite loop, as explained here.

TeX fails with a TeX capacity exceeded, sorry [input stack size=5000] or similar.

\$\endgroup\$
3
  • 1
    \$\begingroup\$ I was waiting for a TeX/LaTeX issue. Those things are more jarring than most - usually, I've forgotten that what I'm doing counts as programming when suddenly I've managed to write something that is infinitely recursive. \$\endgroup\$
    – Ernir
    Commented Feb 20, 2014 at 9:38
  • 1
    \$\begingroup\$ See also codegolf.stackexchange.com/questions/9359/… \$\endgroup\$
    – bwDraco
    Commented Mar 2, 2014 at 3:39
  • 1
    \$\begingroup\$ "TeX capacity exceeded, sorry" TeX is so polite when it fails. \$\endgroup\$
    – Alex A.
    Commented Apr 30, 2015 at 3:08
39
votes
\$\begingroup\$

BF

Will eventually overflow the stack, just depends how long the interpreter makes the stack...

+[>+]
\$\endgroup\$
3
  • 5
    \$\begingroup\$ That code reminds me of game of life. \$\endgroup\$
    – Adam Arold
    Commented Feb 18, 2014 at 1:23
  • 10
    \$\begingroup\$ Strictly speaking, there is no stack in brainfuck. \$\endgroup\$
    – fejesjoco
    Commented Feb 20, 2014 at 15:07
  • 6
    \$\begingroup\$ @fejesjoco Tape, if you wish. \$\endgroup\$
    – Timtech
    Commented Feb 20, 2014 at 15:31
32
votes
\$\begingroup\$

C#, at compile time

There are a number of ways to cause the Microsoft C# compiler to blow its stack; any time you see an "expression is too complex to compile" error from the C# compiler that is almost certainly because the stack has blown.

The parser is recursive descent, so any sufficiently deeply nested language structures will blow the stack:

 class C { class C { class C { ....

The expression parser is pretty smart about eliminating recursions on the side that is commonly recursed on. Usually:

x = 1 + 1 + 1 + 1 + .... + 1;

which builds an enormously deep parse tree, will not blow the stack. But if you force the recursion to happen on the other side:

x = 1 + (1 + (1 + (1 + ....+ (1 + 1))))))))))))))))))))))))))))))))))))))))))...;

then the stack can be blown.

These have the inelegant property that the program is very large. It is also possible to make the semantic analyzer go into unbounded recursions with a small program because it is not smart enough to remove certain odd cycles in the type system. (Roslyn might improve this.)

public interface IN<in U> {}
public interface IC<X> : IN<IN<IC<IC<X>>>> {}
...
IC<double> bar = whatever;
IN<IC<string>> foo = bar;  // Is this assignment legal? 

I describe why this analysis goes into an infinite recursion here:

http://blogs.msdn.com/b/ericlippert/archive/2008/05/07/covariance-and-contravariance-part-twelve-to-infinity-but-not-beyond.aspx

and for many more interesting examples you should read this paper:

http://research.microsoft.com/en-us/um/people/akenn/generics/FOOL2007.pdf

\$\endgroup\$
1
  • 2
    \$\begingroup\$ The exact error message is fatal error CS1647: An expression is too long or complex to compile near (code). The documentation for this error message is here, and it's exactly as you say: "There was a stack overflow in the compiler processing your code." \$\endgroup\$
    – bwDraco
    Commented Feb 24, 2014 at 17:52
32
votes
\$\begingroup\$

On the Internet (used by billion people/day)

Redirects, HTTP status code: 301

For example, on the Dell support website (no offense, sorry Dell):

If you remove the support TAG from the URL then it goes into infinite redirects. In the following URL, ###### is any support TAG.

http://www.dell.com/support/drivers/uk/en/ukdhs1/ServiceTag/######?s=BSD&~ck=mn

I believe it's equivalent to a stack overflow.

\$\endgroup\$
6
  • 5
    \$\begingroup\$ nice way :) firefox tells that it redirects so the request cannot be resolved which is the stackoverflow rquivalent :) \$\endgroup\$
    – masterX244
    Commented Feb 17, 2014 at 16:13
  • 3
    \$\begingroup\$ Note that the redirects are not infinite -- if you hit "Try Again" it adds a few more /Errors/'s to the URL and then stops after receiving HTTP 400 Bad Request. But this arguably makes for a better stack overflow than an infinite redirect does. \$\endgroup\$
    – nandhp
    Commented Feb 17, 2014 at 22:15
  • \$\begingroup\$ @nandhp, I agree, but if you think a third world browser(not modern, IE etc..), They haven't got clue of this situation. \$\endgroup\$
    – dipak
    Commented Feb 18, 2014 at 9:30
  • 2
    \$\begingroup\$ Here's how Wget responds here: pastebin.com/pPRktM1m \$\endgroup\$
    – bwDraco
    Commented Feb 19, 2014 at 20:37
  • 1
    \$\begingroup\$ http://www.dell.com/support/drivers/uk/en/ukdhs1/ServiceTag/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/Errors/... \$\endgroup\$
    – Vortico
    Commented Feb 23, 2014 at 20:26
31
votes
\$\begingroup\$

PHP

A stackoverflow done with looping elements only.

$a = array(&$a);
while (1) {
    foreach ($a as &$tmp) {
        $tmp = array($tmp, &$a);
    }
}

Explanation (hover to see the spoiler):

The program will segfault when the interpreter tries to garbage collect the $tmp array away (when reassigning $tmp here). Just because the array is too deep (self referencing) and then the garbage collector ends up in a recursion.

\$\endgroup\$
4
  • 16
    \$\begingroup\$ PHP's GC can't detect self-referential structures? Really?! Ouch. That is evil. \$\endgroup\$
    – Peter C
    Commented Feb 18, 2014 at 7:19
  • 1
    \$\begingroup\$ Yes, but it's not perfect. There's some reason why while (1) { $a = array(&$a); } or something similar just hits the memory limit… \$\endgroup\$
    – bwoebi
    Commented Feb 18, 2014 at 10:28
  • \$\begingroup\$ yup, I think it's the same reason why PHP is not working properly regarding Object Oriented development either; (abstraction, inheritance etc.) \$\endgroup\$ Commented Feb 24, 2014 at 8:38
  • 1
    \$\begingroup\$ @pythonian29033 care to elaborate? \$\endgroup\$
    – vvondra
    Commented Mar 1, 2014 at 19:51
30
votes
\$\begingroup\$

Java

I did the exact opposite – a program that should obviously throw a stack overflow error, but doesn't.

public class Evil {
    public static void main(String[] args) {
        recurse();
    }

    private static void recurse() {
        try {
            recurse();
        } finally {
            recurse();
        }
    }
}

Hint: the program runs in O(2n) time, and n is the size of the stack (usually 1024).

From Java Puzzlers #45:

Let's assume that our machine can execute 1010 calls per second and generate 1010 exceptions per second, which is quite generous by current standards. Under these assumptions, the program will terminate in about 1.7 × 10291 years. To put this in perspective, the lifetime of our sun is estimated at 1010 years, so it is a safe bet that none of us will be around to see this program terminate. Although it isn't an infinite loop, it might as well be.

\$\endgroup\$
12
  • 3
    \$\begingroup\$ Obvious recursion ... not very interesting. \$\endgroup\$
    – Kami
    Commented Feb 17, 2014 at 14:34
  • 5
    \$\begingroup\$ @Kami Have you tried it? Did you actually get a StackOverflowError? It seems obvious, but it's not. \$\endgroup\$
    – ntoskrnl
    Commented Feb 17, 2014 at 14:49
  • \$\begingroup\$ Just because an exception gets caught doesn't mean it was never thrown. This program throws a stack overflow exception after time O(n) \$\endgroup\$ Commented Feb 17, 2014 at 15:40
  • 1
    \$\begingroup\$ @CodesInChaos Okay, so I double-checked this, and the correct version uses finally rather than catch, and the running time is O(2^n). Answer updated. \$\endgroup\$
    – ntoskrnl
    Commented Feb 17, 2014 at 16:53
  • \$\begingroup\$ @ntorkrnl nice one +1'd ; btw got the compiler to stackoverflow already (compiler runs inside the VM, too fyi) \$\endgroup\$
    – masterX244
    Commented Feb 17, 2014 at 18:41
30
votes
\$\begingroup\$

C#

First post, so please go easy on me.

class Program
{
    static void Main()
    {
        new System.Diagnostics.StackTrace().GetFrame(0).GetMethod().Invoke(null, null);
    }
}

This simply creates a stack trace, grabs the top frame (which will be our last call to Main()), gets the method, and invokes it.

\$\endgroup\$
2
  • \$\begingroup\$ nice way of selfinvoke which isnt that obvious without explain; +1'd \$\endgroup\$
    – masterX244
    Commented Feb 19, 2014 at 19:00
  • \$\begingroup\$ You should comment that code with " what could possibly go wrong ? " :P \$\endgroup\$
    – Spaceman
    Commented Oct 21, 2015 at 6:42
26
votes
\$\begingroup\$

Java

  • In Java 5, printStackTrace() enters an infinite loop.
  • In Java 6, printStackTrace() throws StackOverflowError.
  • In Java 7 and 8, it was fixed.

The crazy thing is that in Java 5 and 6, it does not comes from user code, it happens in JDK's code. No one reasonable suspects that printStackTrace() can be dangerous to execute.

public class Bad {
    public static void main(String[] args) {
        try {
            evilMethod();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static void evilMethod() throws Exception {
        Exception a = new Exception();
        Exception b = new Exception(a);
        a.initCause(b);
        throw a;
    }
}
\$\endgroup\$
2
  • 7
    \$\begingroup\$ yeah; stackoverflows out of nothing are the best friend for codetrolling and a serious headache on hunting em \$\endgroup\$
    – masterX244
    Commented Feb 17, 2014 at 10:31
  • 2
    \$\begingroup\$ If anyone wonders, equivalent code in C# causes an infinite loop. But InnerException property is read-only and is set in constructor, so reflection is necessary to cause this. \$\endgroup\$
    – Athari
    Commented Feb 22, 2014 at 11:38
16
votes
\$\begingroup\$

JavaScript: Non-recursive, iterative function mutation

var f = function() {
    console.log(arguments.length);
};

while (true) {
    f = f.bind(null, 1);
    f();
}

There's no recursion here at all. f will be repeatedly curried with more and more arguments until it can overflow the stack in a single function call. The console.log part is optional in case you want to see how many arguments it takes to do it. It also ensures that clever JS engines won't optimize this away.

Code-golf version in CoffeeScript, 28 chars:

f=->
do f=f.bind f,1 while 1
\$\endgroup\$
0
14
votes
\$\begingroup\$

C# with an epic fail

using System.Xml.Serialization;

[XmlRoot]
public class P
{
    public P X { get { return new P(); } set { } }
    static void Main()
    {
        new XmlSerializer(typeof(P)).Serialize(System.Console.Out, new P());
    }
}

The way it fails is epic, it blew my mind completely:

enter image description here

It is just one frame of a seemingly infinite tripping series of strange images.

This has got to be the weirdest thing ever. Can anybody explain? Apparently, the ever increasing amount of spaces used for indentation cause those white blocks to appear. It happens on a Win7 Enterprise x64 with .NET 4.5.

I haven't actually seen the end of it yet. If you replace System.Console.Out with System.IO.Stream.Null, it dies pretty fast.

The explanation is pretty simple. I make a class which has a single property, and it always returns a new instance of its containing type. So it's an infinitely deep object hierarchy. Now we need something which tries to read through that. That's where I use the XmlSerializer, which does just that. And apparently, it uses recursion.

\$\endgroup\$
5
  • \$\begingroup\$ yeah; serializing ftw :P; but more funny is it when ythe quirk is completely outside of your code like how snakeyaml gets the attributes and one class returns itself in a way that endlesly recurses \$\endgroup\$
    – masterX244
    Commented Feb 20, 2014 at 17:39
  • 1
    \$\begingroup\$ Well, the overflow does happen outside of my code, but the real reason I posted this is because of the unexpected side effect in the console :-) \$\endgroup\$
    – fejesjoco
    Commented Feb 20, 2014 at 17:50
  • \$\begingroup\$ I think the white bits must be to either to do with .Net 4.5 or how your environment is set up, because using .Net 4 (even when run through cmd) I only get spaces, no white blocks. My guess is that either the Win7 Enterprise version of cmd or the .Net 4.5 console emulator treat a certain character combination as 'change the console colour background'. \$\endgroup\$
    – Pharap
    Commented Feb 23, 2014 at 3:13
  • \$\begingroup\$ I can't reproduce it with .NET 4.5 on Win7 x64 Professional with Aero turned on \$\endgroup\$
    – Ray
    Commented Mar 18, 2014 at 13:08
  • \$\begingroup\$ Can't reproduce, either. .NET 4.5, Windows 8.1 Pro. \$\endgroup\$
    – bwDraco
    Commented Oct 2, 2014 at 3:35
13
votes
\$\begingroup\$

bash

_(){ _;};_

While many might recognize that the recursion is obvious, but it seems pretty. No?

Upon execution, you are guaranteed to see:

Segmentation fault (core dumped)
\$\endgroup\$
7
  • 5
    \$\begingroup\$ this one is prettier and worse: _(){_|_;};_ \$\endgroup\$
    – RSFalcon7
    Commented Feb 17, 2014 at 15:03
  • 1
    \$\begingroup\$ @RSFalcon7 Forkbomb alert! (Also, doesn't it need a space after the { to be syntactically correct?) \$\endgroup\$ Commented Feb 17, 2014 at 15:08
  • 3
    \$\begingroup\$ Try this as well :(){:|:;}: \$\endgroup\$ Commented Feb 17, 2014 at 16:17
  • 14
    \$\begingroup\$ Looks like a creepy, mutant emoticon. \$\endgroup\$ Commented Feb 18, 2014 at 21:00
  • 8
    \$\begingroup\$ Bash emoticons: eater of faces, killer of stacks. \$\endgroup\$ Commented Feb 20, 2014 at 19:27
12
votes
\$\begingroup\$

Haskell

(sad but true until at least ghc-7.6, though with O1 or more it'll optimise the problem away)

main = print $ sum [1 .. 100000000]
\$\endgroup\$
6
  • \$\begingroup\$ shouldn't it do a tail call optimization automatically (in sum)? \$\endgroup\$
    – blabla999
    Commented Feb 17, 2014 at 11:55
  • 2
    \$\begingroup\$ @blabla999: tail-calls aren't that relevant in Haskell, it's mostly thunk buildup due to covert lazyness that's causing such problems. In this case, the issue is that sum is implemented in terms of foldl, which does use tail calls, but because it doesn't evaluate the accumulator strictly merely produces a pile of thunks as large as the original list. The problem disappears when switching to foldl' (+), that evaluates strictly and thus returns a WHN in its tail call. Or, as I said, if you switch on GHC's optimisations! \$\endgroup\$ Commented Feb 17, 2014 at 13:13
  • \$\begingroup\$ aah - interesting, so if no one would wait for the thunk (i.e. leaving out the print), the garbage collector would collect them away (from front to back)? \$\endgroup\$
    – blabla999
    Commented Feb 17, 2014 at 13:23
  • 1
    \$\begingroup\$ BTW, none of this is really specified by the Haskell standard: it's merely required that evaluation is non-strict, i.e. a nonterminating computation won't block forever if the result is not fully required. How long it really blocks is up to the implementation, in standard lazy GHC it doesn't block at all until you request the result. \$\endgroup\$ Commented Feb 17, 2014 at 13:44
  • 2
    \$\begingroup\$ haskell is cool. \$\endgroup\$
    – blabla999
    Commented Feb 17, 2014 at 14:15
12
votes
\$\begingroup\$

Smalltalk

This creates a new method on the fly, which
  creates a new method on the fly, which
    creates a new method on the fly, which
      ...
    ...
  ..
and then transfers to it.

An extra little spice comes from stressing stack memory AND heap memory at the same time, by creating both a longer and longer method name, and a huge number as receiver, as we fall down the hole... (but the recursion hits us first).

compile in Integer:

downTheRabbitHole
    |name deeperName nextLevel|

    nextLevel := self * 2.
    name := thisContext selector.
    deeperName := (name , '_') asSymbol.
    Class withoutUpdatingChangesDo:[
        nextLevel class 
            compile:deeperName , (thisContext method source copyFrom:name size+1).
    ].
    Transcript show:self; showCR:' - and down the rabbit hole...'.
    "/ self halt. "/ enable for debugging
    nextLevel perform:deeperName.

then jump, by evaluating "2 downTheRabbitHole"...
...after a while, you'll end up in a debugger, showing a RecursionException.

Then you have to cleanup all the mess (both SmallInteger and LargeInteger now have a lot of wonderland code):

{SmallInteger . LargeInteger } do:[:eachInfectedClass |
    (eachInfectedClass methodDictionary keys 
        select:[:nm| nm startsWith:'downTheRabbitHole_'])
            do:[:each| eachInfectedClass removeSelector:each]

or else spend some time in the browser, removing alice's wonderland.

Here is some from the head of the trace:

2 - and down the rabbit hole...
4 - and down the rabbit hole...
8 - and down the rabbit hole...
16 - and down the rabbit hole...
[...]
576460752303423488 - and down the rabbit hole...
1152921504606846976 - and down the rabbit hole...
2305843009213693952 - and down the rabbit hole...
[...]
1267650600228229401496703205376 - and down the rabbit hole...
2535301200456458802993406410752 - and down the rabbit hole...
5070602400912917605986812821504 - and down the rabbit hole...
[...]
162259276829213363391578010288128 - and down the rabbit hole...
324518553658426726783156020576256 - and down the rabbit hole...
[...]
and so on...

PS: the "withoutUpdatingChangesFile:" was added to avoid having to cleanup Smalltalk's persistent change-log file afterwards.

PPS: thanks for the challenge: thinking about something new and innovative was fun!

PPPS: I like to note that some Smalltalk dialects/versions copy overflowing stack frames to the heap - so these may run into an out-of-memory situation instead.

\$\endgroup\$
2
  • 2
    \$\begingroup\$ LOL +1 for that black magic in its pure form \$\endgroup\$
    – masterX244
    Commented Feb 17, 2014 at 11:42
  • \$\begingroup\$ If I find some time, I may "improve" by using an anonymous method of an anonymous class, to make the darkest rabbit hole ever... \$\endgroup\$
    – blabla999
    Commented Feb 18, 2014 at 10:59
12
votes
\$\begingroup\$

C#

Really big struct, no recursion, pure C#, not unsafe code.

public struct Wyern
{
    double a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z;
}
public struct Godzilla
{
    Wyern a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z;
}
public struct Cyclops
{
    Godzilla a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z;
}
public struct Titan
{
    Cyclops a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z;
}
class Program
{
    static void Main(string[] args)
    {
        // An unhandled exception of type 'System.StackOverflowException' occurred in ConsoleApplication1.exe
        var A=new Titan();
        // 26×26×26×26×8 = 3655808 bytes            
        Console.WriteLine("Size={0}", Marshal.SizeOf(A));
    }
}

as a kicker it crashes the debug windows stating that {Cannot evaluate expression because the current thread is in a stack overflow state.}


And the generic version (thanks for the suggestion NPSF3000)

public struct Wyern<T>
    where T: struct
{
    T a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z;        
}


class Program
{
    static void Main(string[] args)
    {
        // An unhandled exception of type 'System.StackOverflowException' occurred in ConsoleApplication1.exe
        var A=new Wyern<Wyern<Wyern<Wyern<int>>>>();
    }
}
\$\endgroup\$
3
  • \$\begingroup\$ Needs more Generic code methinks :P \$\endgroup\$
    – NPSF3000
    Commented Feb 20, 2014 at 13:02
  • \$\begingroup\$ The it would look like recursion, but it is possible with nested type arguments. \$\endgroup\$ Commented Feb 20, 2014 at 14:05
  • 1
    \$\begingroup\$ Didn't see your C# struct answer before I posted mine. I still have a little different approach, so maybe we let them coexist. \$\endgroup\$ Commented Feb 20, 2014 at 15:21
11
votes
\$\begingroup\$

C#

Faulty implementation of overriden == operator:

public class MyClass
{
    public int A { get; set; }

    public static bool operator ==(MyClass obj1, MyClass obj2)
    {
        if (obj1 == null)
        {
            return obj2 == null;
        }
        else
        {
            return obj1.Equals(obj2);
        }
    }

    public static bool operator !=(MyClass obj1, MyClass obj2)
    {
        return !(obj1 == obj2);
    }

    public override bool Equals(object obj)
    {
        MyClass other = obj as MyClass;
        if (other == null)
        {
            return false;
        }
        else
        {
            return A == other.A;
        }
    }
}

One might say it's obvious that operator== calls itself by using the == operator, but you usually do not think that way about ==, so it's easy to fall into that trap.

\$\endgroup\$
11
votes
\$\begingroup\$

Starting reply using SnakeYAML

class A
{

    public static void main(String[] a)
    {
         new org.yaml.snakeyaml.Yaml().dump(new java.awt.Point());
    }
}

Edit: ungolfed it

Its up to the reader to find out how that works :P (tip: stackoverflow.com)

By the way: the recursion is dynamically made by SnakeYAML (you will notice if you know how it detects the fields it serializes and look then in Point's sourcecode)

Edit: telling how that one works:

SnakeYAML looks for a pair of getXXX and setXXX mthod with same name for XXX and return type of the getter is same as parameter of setter; and surprisingly the Point class has a Point getLocation() and void setLocation(Point P) which returns itself; SnakeYAML doesn't notice it and recurses on that quirk and StackOverflows. Discovered that one when working with them inside a HashMap and asking on stackoverflow.com on it.

\$\endgroup\$
10
votes
\$\begingroup\$

C#

wrongly implemented property getter

class C
{
   public int P { get { return P; } }
}

static void Main()
{
   int p = new C().P;
}
\$\endgroup\$
9
  • 14
    \$\begingroup\$ IMHO. This is a classic example for an obvious recursion... (and so not valid) \$\endgroup\$
    – Ole Albers
    Commented Feb 17, 2014 at 14:57
  • 2
    \$\begingroup\$ Well, it's only obvious once you've done it once and figured out that C# getters don't work the way you may have thought they did. After all, this code is a member variable declaration, so why shouldn't it create an actual member variable? \$\endgroup\$
    – meustrus
    Commented Feb 17, 2014 at 19:30
  • 2
    \$\begingroup\$ This is no more than a convoluted way of doing static void Main() { Main(); } \$\endgroup\$
    – Jodrell
    Commented Feb 18, 2014 at 9:42
  • 5
    \$\begingroup\$ @Jodrell You wouldn't write recursive Main() accidentally. But it's quite simple to write a recursive property accidentally and then be confused by the stack overflow. \$\endgroup\$
    – svick
    Commented Feb 18, 2014 at 17:01
  • 1
    \$\begingroup\$ This would be useful for someone picking up C#. \$\endgroup\$
    – 2rs2ts
    Commented Feb 20, 2014 at 14:10

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