[Date Prev][Date Next][Thread Prev][Thread Next]
- Subject: ldebug.c:512: getfuncname: assert(0)'s
- From: nobody <nobody+lua-list@...>
- Date: Thu, 4 Aug 2016 23:18:25 +0200
Next assertion hit!
-- begin testcase #1 --
xpcall( function() for _=_,_ do end end,
function() debug.getinfo(1,"n") end )
-- end testcase #1 --
What happens? (As far as I understand it...)
The for loop's OP_FORPREP complains that the for limit must be a number
and luaG_runerror's out. ldebug.c's getfuncname assumes that not all
opcodes can result in a call, but xpcall puts the error handling
function on top and violates that assumption. Lo: assert(0)!
Going through all opcodes not explicitly handled and looking at the
code, OP_FORPREP is the only one that explicitly calls luaG_runerror.
All other interesting candidates don't, but can (re)allocate or could
reach a deeper luaG_runerror.
These are: OP_NEWTABLE, OP_SETLIST, OP_CLOSURE, OP_VARARG
Checking for other `luaG_runerror`s...
OP_VARARG can reach a stack overflow while resizing and will
then hit the same assertion:
-- begin testcase #2 --
local handler = function( ) debug.getinfo(1,"n") end
function chks( n, ... )
xpcall( chks, handler, n+1, n, ... )
chks( 0 )
-- end testcase #2 --
NOTE: reduce stack limit or it will take a loong time... I used 1000,
which stacks ~80 calls. With other values, you may also need to add a
few local variables to chks for stack feng shui, so it overflows in
OP_VARARG and not elsewhere.
OP_NEWTABLE (ok) cannot reach the luaG_runerror in setnodevector because
there cannot be too many elements (the scanner table used for the
constants has more entries and overflows earlier, so a test chunk
doesn't even compile.)
I can't find 'luaG_runerror's accessible from OP_SETLIST and OP_CLOSURE.
(There's a branch in luaM_reallocv that leads to luaM_toobig which
luaG_runerror's, but I didn't bother to explore that branch - it's
probably not possible to make a large enough initializer.)
However, there's two alternate sources of errors:
(1) out of memory conditions result in luaD_throw - I can't wrap my head
around that yet, so I can't say for sure whether that can/should call
the error handler set by xpcall.
(2) __gc metamethods that throw an error. As described in a separate
mail, I can't build a test case that runs the error handler. But I
suspect this is / should be possible.
So it's probably a good idea to also handle OP_NEWTABLE, OP_SETLIST, and
OP_CLOSURE (in addition to OP_FORPREP and OP_VARARG).
(Alternatively or in addition to that: contain __gc errors? - I'll write
a separate mail on that.)