mlua icon indicating copy to clipboard operation
mlua copied to clipboard

Avoid panicking if user code exhausts the auxillary thread stack by using a list

Open cheesycod opened this issue 7 months ago • 1 comments

Currently, if user code exhausts the stack, then mlua will fully panic (see https://github.com/mlua-rs/mlua/blob/b57a6239a6544a831514fe6a23b59f55cd56779c/src/state/util.rs#L174).

In such a case, mlua should either fallback from auxiliary thread stack to registry or operate a pool of auxilliary threads.

As it stands right now, there is no way to safely sandbox mlua as any user code which makes and handles too many references can panic and cause issues, especially in a multi tenant environment. Would you be open to a PR which solves this btw by making mlua use a list of auxillary threads instead of just one (I already run mlua with a patch to do this in production and its super helpful)?

For example, consider the following code:

local task = task
if task == nil then
    if zune then
        task = zune.task
    else 
        task = require("@lune/task")
    end
end

local started = os.clock()

local amount = 4000000
local batches = 5
local per_batch = amount / batches

for current = 1, batches do
	local thread = coroutine.running()

	print(`Batch {current} / {batches}`)

	for i = 1, per_batch do
		--print("Spawning thread #" .. i)
		task.spawn(function()
			task.wait(0.1)
			--_TEST_ASYNC_WORK(0.1)
			if i == per_batch then
				print("Last thread in batch #" .. current)
				assert(coroutine.status(thread) == "suspended", `Thread {i} has status {coroutine.status(thread)}`)
				task.spawn(thread)
			end
		end)
	end

	coroutine.yield()
end
local took = os.clock() - started
print(`Spawned {amount} sleeping threads in {took}s`)

return -1

The following code panics in my machine with the auxiliary stack size error due to holding too many luathread references.

Note: I’ve also run into this same panic several times before when coding some algorithms in luau using mlua driver code.

BTW, if you're interested, I took a (WIP rn) stab at solving this/removing this limitation using a growing list of auxiliary threads instead of just one auxiliary thread: https://github.com/cheesycod/mlua/tree/mlua-listofaux (I already run this in production)

cheesycod avatar Jun 06 '25 23:06 cheesycod

there is no way to safely sandbox mlua as any user code which makes and handles too many references can panic and cause issues, especially in a multi tenant environment.

Some references can be stored in the registry (using Lua::create_registry_value). The amount of registry references is usually limited by available memory. The auxiliary thread was designed mostly as a temporary (fast) storage and the current limit of ~1M entries has never been a problem.

khvzak avatar Jun 12 '25 08:06 khvzak