防止 Lua 死循环 [英] Prevent Lua infinite loop
问题描述
我在我的 C# 程序中使用 lua 接口来获得 lua 支持,如果用户提交这样的代码,工作线程将冻结
I use lua interfaces to get lua support in my C# program, the worker thread will freeze if the user submits code like this
while true do end
我有一种方法可以检测无限循环是否正在运行,但我需要一种从 Worker 线程退出 DoString 方法的好方法.有什么想法吗?
I have a way to detect if a infinite loop is running, but I need a nice way of exiting the DoString method from the Worker thread. Any ideas?
@kikito,是的,我正在检测类似的东西.我的问题是我找不到杀死 DoString 方法的干净方法,看起来 Lua 接口主类(Lua)有一些静态依赖项,因为如果我做 lua.Close();
在我的实例上,它会中止 DoString 方法,但是下次我实例化一个 lua 类 new Lua();
时它会崩溃,说一些关于保护性内存的事情
edit: @kikito, Yes Im deteting it something like that. The problem I have is that I cant find a clean way of killing the DoString method, it looks like the Lua interfaces main class (Lua) has some static dependencies, because if I do lua.Close();
on my instance it will abort the DoString method, but the next time I instance an lua class new Lua();
it will crash saying something about protective memory
显示我的 .Close 代码的功能分支https://github.com/AndersMalmgren/FreePIE/tree/detect-and-recover-infite-lua-loop
edit: A feature branch showing my .Close code https://github.com/AndersMalmgren/FreePIE/tree/detect-and-recover-infite-lua-loop
推荐答案
沙盒 Lua
设置钩子根本还不足以防止意外的资源浪费,更不用说滥用了——这是一个简单的例子(时间花在字符串模式匹配上——没有调用调试钩子):
Sandboxing Lua
Setting hooks is not sufficient at all to prevent unintended waste of resources, let alone abuse- here's a simple example (the time is spent during string pattern matching- no debug hooks get called):
s=('a'):rep(20000):match('.-b')
对一段 Lua 代码强制执行时间/内存限制的唯一可靠方法是在自己的进程中运行 Lua 解释器,并使您的操作系统监视该进程.
Lua 的好处是你不需要任何复杂的、依赖于操作系统的沙盒权限设置:你只需要限制时间和内存(合理;在 Windows 上有 作业对象,Unix 有 ulimits-相关:Linux 资源限制),然后保留 os.execute 之类的东西,一半io-library 和模块(如 luasocket)远离脚本编写器(非常简单).
The nice thing with Lua is that you won't need any complicated, OS-dependent permission setup for sandboxing: you just limit time and memory (reasonable; on windows there are Job Objects, Unix has ulimits- relevant: Linux resource limitation) and then keep things like os.execute, half the io-library and modules like luasocket away from the scripter (pretty easy).
你可以处理几乎所有事情(除了违反时间/内存限制)而不会破坏你的 Lua 解释器:只需将用户提供的代码的执行包装在一个 pcall;如果您调用任何可能自己失败的 Lua-API 函数,您需要将它们包装在一个您也可以调用的函数中(或设置一个 Lua 恐慌函数并从那里处理它).
You can handle almost everything (except violation of time/memory limits) without trashing your Lua interpreter: Just wrap the execution of user-supplied code inside a pcall; if you call any Lua-API functions that might fail yourself, you need to wrap them inside a function that you can pcall, too (or set a Lua panic function and handle it from there).
[我不希望看到这个帖子的人认为 debug.sethook 足以用于沙箱,而 stackoverflow 不允许我发表评论(还)]
[I didn't want people glancing at this thread to assume that debug.sethook is adequate for sandboxing, and stackoverflow would not let me comment (yet)]
这篇关于防止 Lua 死循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!