Nmap Development mailing list archives
Re: [NSE] assertion failure in stdnse.sleep()
From: Patrick Donnelly <batrick () batbytes com>
Date: Wed, 17 Oct 2012 17:54:38 -0400
Hi David, On Wed, Oct 17, 2012 at 4:59 PM, David Fifield <david () bamsoftware com> wrote:
One is that calling sleep or another yielding function doesn't seem to work from an exception handler: local stdnse = require('stdnse') prerule = function() return true end action = function() local catch = function() stdnse.sleep(20) end local try = nmap.new_try(catch) try(false) end attempt to yield across metamethod/C-call boundary stack traceback: [C]: in function 'sleep' a.nse:4: in function <a.nse:4> [C]: in function 'try' a.nse:6: in function <a.nse:3> (...tail calls...) I'm confused by this error because I thought that "yield across metamethod/C-call boundary" wasn't a thing anymore with Lua 5.2.
It still exists. A regular lua_call (in C [1]) does not allow coroutine yields to cross the call boundary. We still use lua_call in new_try_finalize. To contrast, many call paths in Lua have been adapted so that you never see this C boundary error anymore, e.g. pcall [2] or dofile [3]. These functions use lua_callk or lua_pcallk. Lua allows yields across these functions because the caller passes a continuation function to Lua. This enables Lua to restart the function when the coroutine is resumed again. See for example, the continuation function for pcall [4]. Continuations are explained in the manual [5]. I wrote a quick patch (untested) which should correct the problem, attached. [1] http://www.lua.org/manual/5.2/manual.html#lua_call [2] http://www.lua.org/source/5.2/lbaselib.c.html#luaB_pcall [3] http://www.lua.org/source/5.2/lbaselib.c.html#luaB_dofile [4] http://www.lua.org/source/5.2/lbaselib.c.html#pcallcont [5] http://www.lua.org/manual/5.2/manual.html#4.7
I thought about using nse_destructor to have l_sleep register a destructor that cancels the timer event; hopefully this happens before the thread is freed.
Destructors are run before the thread is freed. For socket functions, they are able to associate the thread with the socket userdatum to ensure the thread is never collected before the socket userdatum is collected. [This is why it's not necessary to register a destructor for socket methods as, if the thread no longer exists, the nse_restore function will silently fail. This could happen if NSE throws out a timed out script and the nsock callback tries to nse_restore the thread.] Unfortunately, we don't have that convenience for the sleep function. I guess the appropriate way to deal with this unique problem is both making try/catch C continuation compatible (with the patch attached) and adding a destructor to sleep so this situation can't happen again. -- - Patrick Donnelly
Attachment:
finalize-callk.patch
Description:
_______________________________________________ Sent through the nmap-dev mailing list http://cgi.insecure.org/mailman/listinfo/nmap-dev Archived at http://seclists.org/nmap-dev/
Current thread:
- [NSE] assertion failure in stdnse.sleep() Henri Doreau (Oct 06)
- Re: [NSE] assertion failure in stdnse.sleep() David Fifield (Oct 17)
- Re: [NSE] assertion failure in stdnse.sleep() Patrick Donnelly (Oct 17)
- Re: [NSE] assertion failure in stdnse.sleep() Henri Doreau (Nov 06)
- Re: [NSE] assertion failure in stdnse.sleep() Patrick Donnelly (Nov 15)
- Re: [NSE] assertion failure in stdnse.sleep() David Fifield (Nov 21)
- Re: [NSE] assertion failure in stdnse.sleep() Patrick Donnelly (Nov 22)
- Re: [NSE] assertion failure in stdnse.sleep() David Fifield (Nov 23)
- Re: [NSE] assertion failure in stdnse.sleep() Patrick Donnelly (Oct 17)
- Re: [NSE] assertion failure in stdnse.sleep() David Fifield (Oct 17)