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

2
votes
\$\begingroup\$

Java

Recursive reflection:

import java.lang.reflect.Method;

public class StackOverflow {
    public static void main(String[] _) throws Exception {
        Method m = Method.class.getMethod("invoke", Object.class, Object[].class);
        Object[] args = { m, null };
        args[1] = args;
        m.invoke(m, args);
    }
}

I'd like to think that this code doesn't obviously cause a stack overflow, and I'd hope the 1.8MiB of stacktrace it generates counts as 'clearly visible'.

Idea shamelessly lifted from http://bugs.java.com/bugdatabase/view_bug.do?bug_id=4185411.

\$\endgroup\$
2
votes
\$\begingroup\$

C Buffer Overflow

#include <stdio.h>
#include <math.h>

int main()
{
   char buff[20];
   sprintf(buff, "Value of Pi = %f", M_PI);
   return(0);
}
\$\endgroup\$
2
  • \$\begingroup\$ <string.h> isn't used, so you may want to remove it. Also, while being syntactically valid, why did you put the bracket around the 0 in the return statement? \$\endgroup\$
    – user12205
    Commented Feb 20, 2014 at 14:12
  • \$\begingroup\$ Good Point @ace i have removed <string.h> .Was trying to get buf overflow using string functions.Finally found this to be more simple.Brackets are habit :) \$\endgroup\$
    – kaar3k
    Commented Feb 20, 2014 at 14:41
2
votes
\$\begingroup\$

PHP

<?php
header("Location: {$_SERVER['PHP_SELF']}");

Navigating to this page produces this result:

enter image description here

\$\endgroup\$
2
votes
\$\begingroup\$

Apache mod_rewrite done wrong

RewriteEngine On
RewriteRule ^(.+)$ /$1.php [L]

The rule, which is supposed to map URLs such as /about-us to /about-us.php, ends up producing this error in Apache logs (the L flag does not help):

Request exceeded the limit of 10 internal redirects due to probable configuration error. Use 'LimitInternalRecursion' to increase the limit if necessary. Use 'LogLevel debug' to get a backtrace.

\$\endgroup\$
2
votes
\$\begingroup\$

Although it's not a real stack overflow but effects are pretty much the same.

int main()
{
    asm("movl $0, %esp");
}

C++ (since there is no return from main) and i386-like cpus.

ESP is the stack pointer in i386 processor, by doing that, we're pointing the stack out of the memory reserved for it, something similar happens when recursion is involved - just without actually writing to it.

Notice that SIGSEGV is generated not when ESP is changed but when the the program uses the stack, so if we modify the code like this

#include <iostream>

void foo()
{
    std::cout << "hello";
}

int main()
{
    asm("movl $0, %esp");
    foo();
}

we will get the crash at:

Program received signal SIGSEGV, Segmentation fault.
main () at stack.cpp:11
11        foo();

The interesting thing about SO is that you cannot catch SIGSEGV signal by using signal() function since there no stack to call it, but you can provide alternate stack (eg heap allocated) to the sigaction function.

\$\endgroup\$
2
votes
\$\begingroup\$

Java

More API vodoo. This time, the stack trace doesn't hint where the overflow line is actually.

class SO extends JFrame
{
    public static void main(String[]a)
    {
        new SO().setVisible(true);

    }
    public SO()
    {
        setSize(100,100);
        DefaultListModel m = new DefaultListModel();
        JList l = new JList(m);
        m.addElement(m);
        add(l);
    }
}

That derp happened to me once while programming some GUI stuff and I didn't knew where it was from

\$\endgroup\$
7
  • \$\begingroup\$ This is unobvious recursion? Okay.... I thought that adding a list to itself is obvious, but apparently it is not. \$\endgroup\$
    – Justin
    Commented Feb 17, 2014 at 10:20
  • \$\begingroup\$ run it and see what the trace tells you as source of overflow \$\endgroup\$
    – masterX244
    Commented Feb 17, 2014 at 10:22
  • 1
    \$\begingroup\$ Lol; recursive stack trace! \$\endgroup\$
    – Justin
    Commented Feb 17, 2014 at 10:25
  • \$\begingroup\$ However, I couldn't help but notice that it tells you that the error is from DefaultListModel. Also, I use two main steps for debugging: 1. read stack trace to see if there is a hint. 2. either apply the hint or, if there is none, debug by examining code. \$\endgroup\$
    – Justin
    Commented Feb 17, 2014 at 10:26
  • 1
    \$\begingroup\$ btw, you can add java syntax coloring by adding this before the code block: <!-- language: lang-java --> \$\endgroup\$
    – Justin
    Commented Feb 17, 2014 at 10:31
2
votes
\$\begingroup\$

Haskell

A joke I thought of a couple of years back:

import Control.Monad.Fix

main = print(fix error)

gives

"*** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: *** Exception: ... etc.

I'm not getting a stack overflow error, but maybe that is because the Glasgow Haskell Compiler uses lazy evaluation.

The function fix :: (a -> a) -> a gives the first fix point of the function error - fix applies a function to itself. In that sense it is plain and simple recursion. The function error :: [Char] -> a requires a string argument and returns something of any type. That is why it can serve as the argument to another error function.

\$\endgroup\$
2
votes
\$\begingroup\$

Python and the Y combinator

before someone else does it:

(lambda f: (lambda x: x(x))(lambda y: f(lambda : y(y)())))(lambda f: f)()

Please, if you don't know much about lambda calculus, don't downvote this solution because you believe that the recursive call is obvious; it isn't obvious at all. More precisely, lambda x: x(x) or lambda : y(y) or lambda f: f ARE NOT recursive calls but mere functions applying to functions.

\$\endgroup\$
1
  • \$\begingroup\$ In Ruby, ruby -e '->(f){->(x){x[x]}[->(y){f[->{y[y][]}]}]}[->(f){f}][]' \$\endgroup\$
    – kernigh
    Commented May 13, 2014 at 3:39
2
votes
\$\begingroup\$

C with GCC extensions

int main() {
  goto *(void*)main;
  return 0;
}

This will compile without errors and without using any compiler flags when using GCC. GCC allows "computed gotos", where you can jump directly to a pointer. It doesn't look like the goto would cause a stack overflow, but GCC puts a preamble in the main() function that pushes one register to the stack, as can be seen in the produced assembler:

main:
  pushq %rbp
  movq  %rsp, %rbp
  movl  $main, %eax
  jmp   *%rax
\$\endgroup\$
1
vote
\$\begingroup\$

AppleSoft BASIC

0 GOSUB 0

Not so weird but worth mentioning...

\$\endgroup\$
3
  • 1
    \$\begingroup\$ This looks like a direct recursion. \$\endgroup\$ Commented Feb 18, 2014 at 0:42
  • \$\begingroup\$ A agree, very obvious recursion. Don't meet objective nr. 2 of the OP. \$\endgroup\$
    – Paolo
    Commented Feb 18, 2014 at 12:53
  • \$\begingroup\$ The only way to blow the stack in old BASIC is GOSUB or FOR without next. \$\endgroup\$
    – Joshua
    Commented Jun 23, 2014 at 15:21
1
vote
\$\begingroup\$

Python:

Using anonymous recursion. I'm not sure if this is too straight-forward or not, but there are no declared functions, so it seems potentially interesting.

(lambda f:f(f))(lambda f:f(f))
\$\endgroup\$
1
  • 4
    \$\begingroup\$ A lambda calling itself seems to violate part of the rules though (i.e. "Not allowed to use an obvious recursion.") \$\endgroup\$ Commented Feb 18, 2014 at 10:49
1
vote
\$\begingroup\$

Go

I challenge anybody to see the bug, who doesn't already know where it is. I added a few (truthful) comments to explain the code to non-Goers.

Try to find it yourself, if you're so inclined, before reading the comment section below (where somebody will surely spoil it.)

Here is a link to the playground: http://play.golang.org/p/UwunxiXKP7

package main

import "fmt"

// Aim: to define an integer type that by default is printed in hex notation (0xab..)
type hexInt int

// Implementation of the Stringer interface, used by Println for conversion to string.
func (h hexInt) String() string {
    // "%#x" is the alternate form of "%x", which uses lowercase a-f and adds 0x in front.
    return fmt.Sprintf("%#x", h)
}

func main() {
    // Create a variable of type hexInt with the value 42 and print it.
    var h hexInt = 42
    fmt.Println(h)
}
\$\endgroup\$
5
  • \$\begingroup\$ print feedback loop? \$\endgroup\$
    – masterX244
    Commented Feb 17, 2014 at 20:06
  • \$\begingroup\$ "print feedback"? no, not quite. \$\endgroup\$
    – Tobia
    Commented Feb 17, 2014 at 20:07
  • \$\begingroup\$ meant that it gets stuck in the stringification process :P \$\endgroup\$
    – masterX244
    Commented Feb 17, 2014 at 20:19
  • \$\begingroup\$ well, it kind of does ;) \$\endgroup\$
    – Tobia
    Commented Feb 17, 2014 at 20:24
  • \$\begingroup\$ Clever. You can add a link to go playground so that people can test it: play.golang.org/p/UwunxiXKP7 \$\endgroup\$
    – Art
    Commented Feb 18, 2014 at 8:00
1
vote
\$\begingroup\$

Ruby

class Fixnum
  def +(arg)
    self-arg
  end
  def -(arg)
    self+arg
  end
end

reopens the Fixnum class, defines addition as substraction and substraction as addition, then simply do:

3+2

and voila :)

\$\endgroup\$
3
  • \$\begingroup\$ Obvious recursion but still funny. \$\endgroup\$ Commented Feb 20, 2014 at 12:58
  • \$\begingroup\$ Code that redefines numeric operators to return the wrong answer is always suspicious. Your recursive calls to Fixnum#+ and Fixnum#- look obvious to me. \$\endgroup\$
    – kernigh
    Commented May 13, 2014 at 2:20
  • \$\begingroup\$ I did this to a friend, it didn't look obvious to him when he opened up a new feature branch and got stack overflow on an addition ^_^ \$\endgroup\$
    – bbozo
    Commented May 13, 2014 at 5:02
1
vote
\$\begingroup\$

Flash AS3

public class Work extends Sprite
{
    public function Work()
    {
        doIt();
    }

    private function doIt():void
    {
        noYouDoIt();
    }

    private function noYouDoIt():void
    {
        arguments.callee();
    }
}
\$\endgroup\$
1
vote
\$\begingroup\$

Netware:

echo hello > file
cat file >> file

I discovered this (but did not use it) many decades ago. I mentioned it to someone, who did it on a Netware share. The share had no limits, and was also used for scratch space by the netware server itself.

The server filled with this one file end-to-end-to-end, crashed (due to running out of diskspace), and couldn't be brought back up until the file was removed. The file, of course, couldn't be removed until the server was running.

\$\endgroup\$
4
  • 1
    \$\begingroup\$ what happened to your friend and how was the issue bypassed then? \$\endgroup\$
    – masterX244
    Commented Feb 18, 2014 at 20:35
  • \$\begingroup\$ It happened at a polytech. They admins called me on the carpet, and I said I discovered the flaw, and (truthfully) that I didn't do it, and that I didn't know who did (also truthfully - we were in a class, many people overheard it; I don't think my friend did it). It took the admins several hours to fix the problems. I was not asked to help, of course. \$\endgroup\$ Commented Feb 18, 2014 at 21:39
  • \$\begingroup\$ @masterX244: obvious bypass is to boot from another media, then access this disk and delete the file. \$\endgroup\$ Commented Feb 20, 2014 at 1:17
  • \$\begingroup\$ Netware used their own proprietary filesystem. \$\endgroup\$ Commented Feb 20, 2014 at 20:21
1
vote
\$\begingroup\$

Javascript

Tested in Chrome:

var a = Array(10000000);
(function(){}).apply(this, a);
\$\endgroup\$
1
vote
\$\begingroup\$

C

void main()
{
    while(1)
        *(char*)alloca(1000)=0;
}

Funnily, without =0 it will rotate indefinitely because it'll just subtract stack pointer without causing any stack accesses.

\$\endgroup\$
1
vote
\$\begingroup\$

C#

  public static int i
  {
      set { i = value; }
  }
  static void Main(string[] args)
  {
      i = 0;
  }
\$\endgroup\$
1
  • 1
    \$\begingroup\$ obvious recursion. Same as int i() { return i(); } \$\endgroup\$
    – Reactgular
    Commented Feb 18, 2014 at 23:01
1
vote
\$\begingroup\$

Common problem in a Rails model

after_save :bump_version

# a lot of code....

private

def bump_version
  create_new_version_record
  update_attribute(:version, version+1)
end
\$\endgroup\$
1
vote
\$\begingroup\$

Haskell

import Control.DeepSeq
makeFunc n = \input -> (newfunc input) `deepseq`
    unlines [ "Function number "++(show n)++"was called with "++input
            , "Now calling the next function."
            , newfunc input]
            where
                newfunc=makeFunc (n+1)

main=putStrLn ((  makeFunc (0::Double)  ) "Input")

In this, each function creates a new one, and calls it. Note that this is no recursion, in that no function call itself.

\$\endgroup\$
3
  • \$\begingroup\$ what language?; \$\endgroup\$
    – masterX244
    Commented Feb 19, 2014 at 19:45
  • \$\begingroup\$ Sorry, I changed it, and accidentially deleted the header. \$\endgroup\$ Commented Feb 19, 2014 at 19:46
  • \$\begingroup\$ derps happen sometimes, no issue; thats why i just asked and didnt said something not so friendly \$\endgroup\$
    – masterX244
    Commented Feb 19, 2014 at 19:47
1
vote
\$\begingroup\$

excel vba

Private Sub Worksheet_Change(ByVal Target As Range)
[a1] = 1
End Sub

place code into any worksheet

stack will overflow (in vba, displayed as an out of memory error) as each change to the worksheet triggers another change.

\$\endgroup\$
1
vote
\$\begingroup\$

Well just since I'm bored.

int main()
{
   char *ptr;
   ptr = &ptr - sizeof(ptr);
   while(1)
      *--ptr = 0;
}

Invokes undefined behavior that trips the guard page the same way a stack overflow does.

\$\endgroup\$
1
vote
\$\begingroup\$

Vim

:se maxf<tab>=0<CR>
:help<CR>

Produces E132: Function call depth is higher than 'maxfuncdepth', vim's equivalent of a stack overflow. (Several times, actually)

\$\endgroup\$
1
  • \$\begingroup\$ This works by reducing VimL's stack size and then invoking a simple command. It'd also be possible to achieve similar errors using any standard recursion approach. \$\endgroup\$ Commented Feb 20, 2014 at 7:07
1
vote
\$\begingroup\$

ANS Forth:

0 >in 2dup ! !

which leads to:

$ gforth
Gforth 0.7.0, Copyright (C) 1995-2008 Free Software Foundation, Inc.
Gforth comes with ABSOLUTELY NO WARRANTY; for details type `license'
Type `bye' to exit
0 >in 2dup ! !                                          
:1: Stack overflow
0 >in 2dup >>>!<<< !
Backtrace:
$B71DF6EC r> 
$B71D34A4 perform 
$B71DD654 (search-wordlist) 
$3 
$0 
$B71DD734 (vocfind) 
$B71D34A4 perform 
$B71D351C (search-wordlist) 
$B71D3FF4 find-name 

In fact, the 2nd ! is never executed.

>in is an integer variable that contains the current position within the input line, the program attempts to write zero to >in two times, but after the first write (!) the input pointer is reset to the start of input line, and the 2nd pair of values is left on the stack...

\$\endgroup\$
3
  • \$\begingroup\$ whats the black magic? cant get behind it somehow \$\endgroup\$
    – masterX244
    Commented Feb 20, 2014 at 11:33
  • \$\begingroup\$ the 1st ! (store) sets the input pointer >in to the beginning of the line. After executing !, the interpreter begins to interpret the line from the very beginning. So anything ending with 0 >in ! is an endless loop. To get a stack overflow, we need to leave something on the stack. I did 2dup, it leaves an extra copy of 0 and the address of >in. And the 2nd ! is never executed because >in gets reset before the interpreter can reach it. \$\endgroup\$ Commented Feb 20, 2014 at 11:48
  • \$\begingroup\$ Note that after declaring variable x the code 2 x 2dup ! ! (in C it would be x = x = 2;) is absolutely valid, although stupid. \$\endgroup\$ Commented Feb 21, 2014 at 5:05
1
vote
\$\begingroup\$

Another one!

Ruby

class Foo
  def method_missing *args, &block
    foo
  end
end

Foo.new.stack_overflow!
SystemStackError: stack level too deep
        from /home/bbozo/.rvm/rubies/ruby-1.9.3-p286/lib/ruby/1.9.1/irb/workspace.rb:80
Maybe IRB bug!
\$\endgroup\$
1
  • \$\begingroup\$ nice one :) especially when the error is spitted in IRB :) \$\endgroup\$
    – masterX244
    Commented Feb 20, 2014 at 14:06
1
vote
\$\begingroup\$

PHP

$a = array('call_user_func_array', &$a);
$a[0]($a[0], $a);

Process exited with code 139.

Compatible from 4.3 to 5.6

\$\endgroup\$
1
vote
\$\begingroup\$

Python

>>> class C:
...     def __setattr__(self, k, v):
...             self.k = v
...
>>> C().x = 10
...
  File "<stdin>", line 3, in __setattr__
RuntimeError: maximum recursion depth exceeded while calling a Python object

__getattribute__ will also do this in a similar way.

\$\endgroup\$
1
vote
\$\begingroup\$

C: "Hello World" format

#include <stdio.h>
int main(){
    (*printf+285)("Hello World\n");
}

This is actually a recursive call that fails when the stack get too big, but it is definitely not an obvious one.

\$\endgroup\$
1
vote
\$\begingroup\$

Haskell

I'm surprised nobody posted this already... Maybe it's too obvious?

data Foo = Bar

instance Eq Foo where

main = print (Bar == Bar)

Naturally, Bar == Bar should evaluate to True. So this program should just print "True" and then exit. However, that's not what the empty instance Eq Foo declaration does. ;-)

\$\endgroup\$
1
vote
\$\begingroup\$

C#

This will stack overflow the CLR I think, and report that type could not be loaded.

public struct Titan 
{
    public Pluto Data { get; set; }
}

public struct Pluto 
{
    public Titan Data { get; set; }
}

class Program
{
    static void Main(string[] args)
    {
        //System.TypeLoadException was unhandled
        //Message="Could not load type 'ConsoleApplication1.Titan' from assembly 'ConsoleApplication1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'."
        //Source="ConsoleApplication1"
        //TypeName="ConsoleApplication1.Titan"
        //StackTrace:
        //     at ConsoleApplication1.Program.Main(String[] args)
        //     at System.AppDomain._nExecuteAssembly(Assembly assembly, String[] args)
        //     at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
        //     at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
        //     at System.Threading.ThreadHelper.ThreadStart()
        Titan t;
    }
}
\$\endgroup\$
1
  • \$\begingroup\$ The JIT might optimize the statement away if it is not used. That is what I had a WriteLine() statement. \$\endgroup\$ Commented Feb 24, 2014 at 0:18

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