lua-users home
lua-l archive

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


You can inspect the 'dead' coroutine using the debug library, e.g. add "print(debug.traceback(thread))". On my system the output is:

stack traceback:
co.lua:9: in upvalue 'recurse'
co.lua:9: in upvalue 'recurse'
co.lua:9: in upvalue 'recurse'
co.lua:9: in upvalue 'recurse'
co.lua:9: in upvalue 'recurse'
co.lua:9: in upvalue 'recurse'
co.lua:9: in upvalue 'recurse'
co.lua:9: in upvalue 'recurse'
co.lua:9: in upvalue 'recurse'
co.lua:9: in upvalue 'recurse'
... (skipping 2499976 levels)
co.lua:9: in upvalue 'recurse'
co.lua:9: in upvalue 'recurse'
co.lua:9: in upvalue 'recurse'
co.lua:9: in upvalue 'recurse'
co.lua:9: in upvalue 'recurse'
co.lua:9: in upvalue 'recurse'
co.lua:9: in upvalue 'recurse'
co.lua:9: in upvalue 'recurse'
co.lua:9: in upvalue 'recurse'
co.lua:9: in upvalue 'recurse'
co.lua:13: in function <co.lua:13>


If you put "thread = nil" before the loop at the end the thread object and the stack will be collected. 

In short, it's not a bug, it's a feature 😀

Ge'

On Mon, Jul 24, 2023 at 8:52 AM Sergey Zakharchenko <doublef.mobile@gmail.com> wrote:
Hello list,

After a stack overflow in a coroutine, the GC appears not to clean up
its stack. This seems to happen at least in Lua 5.1.5 and one built
from Git commit ea39042e13645f63713425c05cc9ee4cfdcf0a40 (5.4.6+)
(Debian amd64).

If you run the following script with relatively small numeric
arguments (<16000 in 5.1.5, <499000 in the custom 5.4.6), everything
is as expected (collectgarbage("count") gets reduced after
collections). As you increase the argument, you see that the value
reported gets larger and isn't reduced by collections.

#!/usr/bin/env lua

-- pick argument values close to LUAI_MAXSTACK/2
-- (function + argument = 2).
local depth=tonumber((...)) or 500000

local function recurse(n)
    if n > 0 then
        recurse(n-1)
    end
end

local thread = coroutine.create(function (n)  recurse(n);
coroutine.yield("completed") end)
collectgarbage("collect")
print("start",coroutine.resume(thread, depth))
print(coroutine.status(thread))
for i=1, 10 do
    collectgarbage("collect")
    print(i, collectgarbage("count")*1024)
end

Sample outputs:

$ lua test.lua 16000
start    true    completed
suspended
1    122315
2    53259
3    35787
4    31419
5    31419
6    31419
7    31419
8    31419
9    31419
10    31419

$ lua test.lua 17000
start    false    ./test.lua:9: stack overflow
dead
1    2175269
2    2176085
3    2176085
4    2176085
5    2176085
6    2176085
7    2176085
8    2176085
9    2176085
10    2176085

I know it makes little sense to hold onto a dead coroutine but this
behaviour looks suspicious...

Best regards,

--
DoubleF


--