lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]

It was thus said that the Great Coroutines once stated:
> On Wed, Jul 9, 2014 at 7:19 PM, Hao Wu <> wrote:
> > I am not sure about any particular case to intend overflowing the call
> > stack, but here is to threshold the recursive looking up to 100 or something
> > - note that __index can be a function that does anything, a.k.a. unavoidable
> > infinite loop.
> A stack overflow is something I might want to catch within pcall(), is
> what I am saying.  

  You can catch a Lua stack overflow with pcall().

	depth = 0
	function foo() depth = depth + 1 foo() end
	okay,err = pcall(foo)
	19996   false   stdin:1: stack overflow

> Someone a day ago in #lua told me that there is a limit on the recursion
> depth of C function calls, or something like it.

  Yes, it's the size of the program stack (on a Unix system, you can see the
default value with the command line "ulimit -s"---be aware the return value
is measured in kilobytes), minus the stack frames to the recursive function,
divided by the stack frame size of the recursive function.  It might be a
sizable number (on the system I ran the code below on, it was 1,449,652
calls before it failed, but the default stack size is limited; your milage
may vary [4]).

  And you can't portably catch a C stack overflow.  There are ways of doing
it [1] but they're system specific.  You might think you can do:

	#include <signal.h>
	#include <stdio.h>
	#include <stdlib.h>
	#include <setjmp.h>

	unsigned long depth;
	jmp_buf       trouble;
	void segv(int sig)
	void foo(void)
	int main(void)
	  if (setjmp(trouble) != 0)
	    return EXIT_FAILURE;  

	  if (signal(SIGSEGV,segv) == SIG_ERR)
	    return EXIT_FAILURE;
	  return EXIT_SUCCESS;

but it won't work.  On systems without memory protection, at best, the code
will fall into an infinite loop; at worse, it might corrupt the entire
system [2].  On systems with memory protection [3] it won't corrupt the
system, but it probably won't work as intended.  When I ran this, I kept
getting "Segmentation fault (core dumped)" because:  when I ran out of stack
space, there was no space to save the CPU state before calling my signal
handler, so I was most likely getting a double fault.  

> I wasn't happy about that because I was trying to port something
> I saw in javascript so I could find the maximum recursion depth before
> stack overflow.  I wouldn't do it with __index, but infinite loops are
> sometimes desired is all I am saying.  I wouldn't limit something
> because I think others might not want that ~

  Intentional infinite loops are okay; it's the unintentional ones that

  -spc (Stupid computers and their finite memory!)

[1]	And I don't recommend it.  No, really, don't do it.

[2]	If it hits memory mapped I/O, for instance.

[3]	And I did run this code on such a system

[4]	When I set the stack size to unlimited, I reached 268,400,386 calls
	before I got a SIGBUS error, and the system seized up for about two
	minutes as a metric butload of memory was paged and back again.