[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: C stack size
- From: Roberto Ierusalimschy <roberto@...>
- Date: Mon, 3 Jun 2019 11:01:41 -0300
As already discussed, Lua 5.4 is using a "non stackless" implementation.
That means that it uses the C stack for recursion in Lua functions.
Because of that, the maximum depth of recursion is much lower in 5.4
than it was in 5.3. In Linux, that limit could be around 20000 calls,
which seems more than enough. On other systems, however (e.g., Windows),
that limit must be much lower.
I am attaching here a test file that should check whether the limit
is good enough for your machine. The output should be something like
this:
$ lua cstack.lua
testing C-stack overflow detection
testing simple recursion:
2164 final count: 2165
testing stack overflow in message handling
2413 final count: 2414
testing recursion inside pattern matching
testing stack-overflow in recursive 'gsub'
181 final count: 181
testing stack-overflow in recursive 'gsub' with metatables
272 final count: 272
OK
Or this if the limit is too high for the machine's stack:
$ ulimit -S -s 400; lua cstack.lua
testing C-stack overflow detection
testing simple recursion:
1758 Segmentation fault (core dumped)
(The '1758' is how many recursions it did before crashing.)
In our tests, the current limit of 2200 was about right for
Windows 7/VS 2010. For Linux/gcc, it works with a limit of 30000.
If you could run this test in your machine, that would be helpful.
It would be even more helpful if you could play with the
constant LUAI_MAXCSTACK and find its maximum value that the
test does not crash. (You can change LUAI_MAXCSTACK in luaconf.h
or define it with a compiler option.)
Many thanks,
-- Roberto
-- $Id: testes/cstack.lua $
-- See Copyright Notice in file all.lua
print"testing C-stack overflow detection"
-- Segmentation faults in these tests probably result from a C-stack
-- overflow. To avoid these errors, recompile Lua with a smaller
-- value for the constant 'LUAI_MAXCCALLS' or else ensure a larger
-- stack for the program.
local function checkerror (msg, f, ...)
local s, err = pcall(f, ...)
assert(not s and string.find(err, msg))
end
local count
local back = string.rep("\b", 8)
local function progress ()
count = count + 1
local n = string.format("%-8d", count)
io.stderr:write(back, n)
end
do print("testing simple recursion:")
count = 0
local function foo ()
progress()
foo()
end
checkerror("stack overflow", foo)
print("\tfinal count: ", count)
end
do print("testing stack overflow in message handling")
count = 0
local function loop (x, y, z)
progress()
return 1 + loop(x, y, z)
end
local res, msg = xpcall(loop, loop)
assert(msg == "error in error handling")
print("\tfinal count: ", count)
end
-- bug since 2.5 (C-stack overflow in recursion inside pattern matching)
do print("testing recursion inside pattern matching")
local function f (size)
local s = string.rep("a", size)
local p = string.rep(".?", size)
return string.match(s, p)
end
local m = f(80)
assert(#m == 80)
checkerror("too complex", f, 200000)
end
do print("testing stack-overflow in recursive 'gsub'")
count = 0
local function foo ()
progress()
string.gsub("a", ".", foo)
end
checkerror("stack overflow", foo)
print("\tfinal count: ", count)
print("testing stack-overflow in recursive 'gsub' with metatables")
count = 0
local t = setmetatable({}, {__index = foo})
foo = function ()
count = count + 1
progress(count)
string.gsub("a", ".", t)
end
checkerror("stack overflow", foo)
print("\tfinal count: ", count)
end
print'OK'