[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Preventing Lua scripts that never return from freezing the host application
- From: Jim Whitehead II <jnwhiteh@...>
- Date: Tue, 3 Nov 2009 16:14:48 +0000
On Tue, Nov 3, 2009 at 3:53 PM, Peter Cawley <lua@corsix.org> wrote:
> On Tue, Nov 3, 2009 at 3:46 PM, Christian Tellefsen
> <christian.tellefsen@funcom.com> wrote:
>> I'm investigating using Lua as a scripting language for content designers.
>> If I want to make sure that none of the designer-supplied scripts can loop
>> forever and freeze the host application, how would I do that?
>>
>> Sample problem code:
>>
>> f = coroutine.create(function() while true do print('x') end end) -- No
>> yield()
>> coroutine.resume(f) -- Oh no
>>
>> Some possible solutions I'm looking at:
>> - Change the interpreter, so that it returns an error if we've spent too
>> much time / done too many operations.
>>
>> - Run Lua in a separate thread and somehow stop it if it takes too long.
>>
>> - Wrap f in code that calls yield(), and disallow bytecode in f that
>> contains loops or backwards jumps. This would of course greatly limit what
>> can be in a script. Something like this:
>>
>> mycode.create = function(f)
>> assert(mycode.checknoloops(f))
>> return coroutine.create(function() f() coroutine.yield() end)
>> end
>>
>> - Alternatively, don't fix it in code, just spend some time on teaching the
>> content designers to write their scripts right.
>>
>> If you have any suggestions or experience on how to best attack this
>> problem, I'd be grateful.
>>
>> Cheers,
>> Christian.
>>
>
> I would use lua_sethook, with LUA_MASKCOUNT and some value between 50
> and 500. This will call your hook function at a regular interval, and
> then you can abort if things are taking too long. You'll have to do
> this for each thread though, so you'll have to export slightly tweaked
> versions of the coroutine.xyz functions to your scripts to add
> automatic hooking.
Keep in mind that for certain C functions (like string.find) won't
call your debug hook in them, so a user script can still tie up the
system in what appears to be an infinite loop, but really is just code
that takes a long time to run (all without your hook being called).
- Jim