Jump to content




The stack and you: How to not crash your program


  • You cannot reply to this topic
10 replies to this topic

#1 Fatal_Exception

  • New Members
  • 105 posts

Posted 21 September 2012 - 06:10 AM

This started as a quick reply to an Ask A Pro thread, but ended up becoming a wall of text lesson on stack overflows that might prove useful as a reference. The technical details are not completely accurate, but I think it illustrates the concept.

View Postcowman001, on 21 September 2012 - 01:01 AM, said:

how do i reset the stack? for future reference?

The stack is internal to lua, storing the current state of the program. You can't simply 'reset' it, short of restarting the computer. You can avoid overflowing it by making sure you return from any functions you call, in a timely manner.

It works something like this:
Every time you call a function (or start a new shell process), lua puts the current position in the program on the stack, then calls the function. Any parameters or local variables inside a function also go on the stack.
When you return from a function, it pops (removes from the stack) all the local variables, and returns to where the function was called from.
Unless you're very careful when you make recursive calls (functions calling themselves or their 'ancestors'), you continually push more data onto the stack, but never pop it back off by returning. Eventually you run out of stack memory, and your program crashes.

Consider the following badly-behaved example:
Spoiler

When run, it will rapidly call both functions in succession, adding to the stack each time, but never returning.

Output:
Spoiler

Because the functions never reach the 'end', they don't get a chance to pop off the data they added to the stack, so it keeps growing.

Let's have a look at what the stack looks like as we run the program:
Spoiler

In contrast, here's a well-behaved program:
Spoiler

When we first enter the function, it puts the return address on the stack, so the stack looks like:
funcOne() -- <return to line 10>

When we hit the end of the function, the return address gets popped, leaving the stack empty -- exactly as it found it.
Since we leave the stack in the same condition as it was when we started, it can never overflow.

#2 Sammich Lord

    IRC Addict

  • Members
  • 1,212 posts
  • LocationThe Sammich Kingdom

Posted 21 September 2012 - 08:00 AM

Very well explained. I remember when I was a noob and got stack overflows constantly and then I would scream out "Fuck you stack overflow error!".
But very nice post, it will help new people out a lot.

#3 Mr. Fang

  • Members
  • 82 posts

Posted 21 September 2012 - 04:59 PM

Not going to lie I was about to ask this question in the forums, mainly because I've never experienced one, but it sounds like the ability to crash your computer because you had too many windows open.

#4 Cranium

    Ninja Scripter

  • Moderators
  • 4,031 posts
  • LocationLincoln, Nebraska

Posted 21 September 2012 - 05:36 PM

View PostMr. Fang, on 21 September 2012 - 04:59 PM, said:

Not going to lie I was about to ask this question in the forums, mainly because I've never experienced one, but it sounds like the ability to crash your computer because you had too many windows open.
That is a very apt analogy.

#5 Geforce Fan

  • Members
  • 846 posts
  • LocationMissouri, United States, America, Earth, Solar System, Milky Way, Universe 42B, Life Street, Multiverse, 4th Dimension

Posted 10 October 2012 - 11:54 PM

Doesn't a stack overflow happen what you shell.run('') ; too many times? How do you fix that one? Is there a shell.quit() or somthing?

#6 Lyqyd

    Lua Liquidator

  • Moderators
  • 8,465 posts

Posted 11 October 2012 - 12:55 AM

Some technical corrections:
  • The stack is dealt with in the java code, by LuaJ.
  • Lua is compiled to bytecode, so the jumping around between functions is actually between different locations in memory, not different lines in the file.
  • Cross-recursion is not the only way to trigger a stack overflow, thought it's not a bad example. Other ways include:
    • Plain recursion
    • Recursion using shell.run()
    • Cross-recursion using shell.run()
    • Improper tail-call recursion


#7 Fatal_Exception

  • New Members
  • 105 posts

Posted 11 October 2012 - 01:32 AM

All true, and details I basically glossed over to simplify things. I wanted to present an idea of what the stack was conceptually without delving too much into technicalities. I probably should have expanded on the different forms of recursion though.

The major take home point being, if you aren't careful to clean up after yourself, your program will crash eventually.

#8 PixelToast

  • Signature Abuser
  • 2,265 posts
  • Location3232235883

Posted 11 October 2012 - 03:01 AM

a easier way to do it is to create your own stack in a table storing coroutines or whatever data you want to process
thats how my new advanced serialization works :3 only a couple stack levels :P/>
i also plan on making my own os with its own, unlimited stack

#9 bbqroast

  • Members
  • 124 posts

Posted 30 October 2012 - 10:18 PM

Out of interest, will this cause a "stack leak":
function foo()
  // Regular code
end
Because it has no return call? A lot of my void functions I just leave tail less, as they return automatically when they hit the end marker, but does that prevent them from getting kicked off the stack?

#10 Lyqyd

    Lua Liquidator

  • Moderators
  • 8,465 posts

Posted 31 October 2012 - 05:13 AM

No, as long as the function eventually finishes executing and returns (with or without an explicit return keyword doing the returning), it will be removed from the stack. The issue arises when a function is waiting on something else to finish before exiting (such as another call to itself), but nothing ever exits. You fill up the stack with functions all waiting for the next function up the stack to exit until the stack gets too tall and overflows.

#11 bbqroast

  • Members
  • 124 posts

Posted 17 November 2012 - 01:30 PM

Cool, thanks for the advice :)/>.





1 user(s) are reading this topic

0 members, 1 guests, 0 anonymous users