1
votes

I've been looking at lua and lvm.c. I'd very much like to implement an interface to allow me to control the VM interpreter state.

Cooperative multitasking from within lua would not work for me (user contributed code)

The debug hook gets me only about 50% of the way there, instruction execution limits, but it raises an exception which just crashes the running lua code - but I need to be able to tweak it even further.

I want to create a system where 10's of thousands of lua user scripts are running - individual threads would not work, and the execution limits would cause headache for beginning developers, I'm going to control execution speeds too. but ultimately

while true do

end

will execute forever, and I really don't care that it is.

Any ideas, help or other implementations that I could look at?

EDIT: This is not about sandboxing pretend I'm an expert in that field for this conversation

EDIT: I do not want to use an internally ran lua code coroutine based controller.

EDIT: I want to run one thread, and manage a large number of user contributed lua scripts, an external process level control mechansim would not scale at all.

4

4 Answers

2
votes

You can search for Lua Sandbox implementations; for example, this wiki page and SO question provide some pointers. Note that most of the effort in sandboxing is focused on not allowing you to execute bad code, but not necessarily on preventing infinite loops. For better control you may need to combine Lua sandboxing with something like LXC or cpulimit. (not relevant based on the comments)

If you are looking for something Lua-based, lightweight, but not necessarily 100% foolproof, then you can try running your client code in a separate coroutine and set a debug hook on that coroutine that will be triggered every N-th line. In that hook you can check if the process you are running exceeded its quotes. You also need to take care of new coroutines started as those need to have their own hooks set (you either need to disable coroutine.create/wrap or to replace them with something that sets the debug hook you need).

The code in this case may look like:

local coro = coroutine.create(client_func)
debug.sethook(coro, debug_hook, "l", 1000) -- trigger hook on every 1000th line

It's not foolproof, because it may block on some IO operation and the debug hook will not help there.

[Edit based on updated question and comments]

Between "no lua code coroutine based controller" and "no external process control mechanism" I don't think you are left with much choice. It may be that your only option is to run one VM per user script and somehow give ticks to those VMs (there was a recent question on SO on this, but I can't find it). Before going this route, I would still try to do this with coroutines (which should scale to tens of thousands easily; Tir claims supporting 1M active users with coroutine-based architecture).

The mechanism would roughly look like this: you install the debug hook as I shown above and from that hook you yield back to your controller, which then decides what other coroutine (user script) to resume. I have this very mechanism working in the Lua debugger I've been developing (although it only does it for one client script). This doesn't protect you from IO calls that can block and for that you may still need to have a watchdog at the VM level to see if it's been blocked for longer than needed.

If you need to serialize and deserialize running code fragments that preserve upvalues and such, then Pluto is probably your only option.

0
votes
0
votes

Take a look at lulu. It is lua VM written on lua. It's for Lua 5.1 For newer version you need to do some work. But it's then you really can make a schelduler.

0
votes

Take a look at this, https://github.com/amilamad/preemptive-task-scheduler-for-lua I maintain this project. It,s a non blocking preemptive scheduler for running lua code. Suitable for long running game scripts.