[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: debug.getlocal from within return hook
- From: "书呆彭, Peng Yi" <nerditation@...>
- Date: Tue, 19 May 2015 13:50:42 +0800
在 2015/5/19 0:32, Philipp Janda 写道:
Hi!
Is it supported to enumerate/query the local variables of a function from within a return hook?
local variables are scoped; as I understand, the when the return hook get called, it still _within_ the
returning function. the manual says [http://www.lua.org/manual/5.3/manual.html#lua_sethook]:
The return hook: is called when the interpreter returns from a function.
The hook is called *just before* Lua leaves the function.
There is no standard way to access the values to be returned by the function.
I have some difficulties on all Lua versions since 5.1:
Lua 5.1:
func a 10
func b table: 0x18338e0
func c function: 0x182e890
func d true
func e string
(apparently all locals are already gone).
Lua 5.2:
func a 10
func b table: 0x1b3ed10
func c function: 0x1b3f4c0
func d true
func e string
HOOK a table: 0x1b3fbc0
HOOK b function: 0x1b3c850
HOOK c 3
HOOK d c
HOOK e c
(local variable names are still there, values are wrong)
Lua 5.3:
func a 10
func b table: 0x8fbc80
func c function: 0x8fbcc0
func d true
func e string
HOOK a table: 0x8f77b0
HOOK b function: 0x8f7590
HOOK c 3
HOOK d c
HOOK e c
(same as 5.2)
LuaJIT seems to manage:
func a 10
func b table: 0x40622d08
func c function: 0x4061f780
func d true
func e string
HOOK a 10
HOOK b table: 0x40622d08
HOOK c function: 0x4061f780
HOOK d true
HOOK e string
Test script attached.
I checked the attached script and examined the source code of Lua.
interestingly, if you return something (even `nil') instead of nothing from that function,
you'll get the expected result (I have Lua 5.2 installed, but I believe it applies to 5.3):
--------------------------
func a 10
func b table: 000000000052BB20
func c function: 000000000052CDE0
func d true
func e string
HOOK a 10
HOOK b table: 000000000052BB20
HOOK c function: 000000000052CDE0
HOOK d true
HOOK e string
---------------------------
for me, it feels like a bug (or call it a glitch) of Lua in this special situation.
I'll explain it in detail.
Lua calls the debug hook in function `luaD_poscall' (ldo.c), which is called by the VM
when executing the OP_RETURN instruction (lvm.c). but the OP_RETURN instruction will first
adjust the stack, according to the returning values.
this is all good, except when the function returns NOTHING, in which case the RA register
of OP_RETURN is 0, so the VM simply empty the the (still semantically active) stack frame.
thus you actually get values probably located in the stack frame of the hook itself
when you call debug.getlocal.
when the function returns NOTHING (either an explicit `return' statement or implicitly),
Lua generate this opcode:
RETURN 0 1
when the function returns some value (e.g. nil), Lua generate this opcode:
LOADNIL 8 0
RETURN 8 2
in the latter case, the VM still adjust the stack before calling the return hook, but since
the returnning values are loaded at the top of the stack, the active stack frame holding the
local variables is not destroyed, so your hook can now get the expected results.
For now I'll probably try to use the line hook, discarding the results of all calls except the last for each function.
see the workaround I mentioned above.
Thx,
Philipp
--
the nerdy Peng / 书呆彭 / Sent from Thunderbird