lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On 4/04/2011, at 10:44 PM, Mike Pall wrote:

> Geoff Leyland wrote:
>> Has anyone got any bright ideas about how to detect tail calls
>> or returns from the debug interface in LuaJIT?  Any chance that
>> LuaJIT could report tail returns like Lua does (without
>> compromising performance)?  Or that it could break the debug
>> interface and add a hook argument for the "call" action that
>> tells you whether the call is a tail call?
> 
> Lua 5.2 has an extra LUA_HOOKTAILCALL event. I can't use that for
> LuaJIT, but I could pass the info in the line number. E.g. -1 for
> regular calls and -2 for tail calls.

That'd be great!  Then I can just add a tailcall event to the collector and let the analyser work out the consequences.  It'd be different from the way Lua gets handled, but the two options are kind of orthogonal, so I wouldn't even need to know which I was tracing.

> Not sure if this breaks anything in other debuggers.

Anyone care to object?  At the moment, ar->currentline is -1 for calls and returns, so I can't imagine that too many tools are relying on it at all.  Maybe some have an "if (ar->currentline == -1)" to work out that it's not a line hook?

> The pseudo-line number would only be accessible from a C hook, not a Lua hook set with debug.sethook().

Ah, ok.  That's fine - I'm using a C hook for Lua (with a fallback Lua hook if the C hook hasn't been built).  I had imagined without any data that with LuaJIT a Lua hook might actually be faster than a C hook since there's potential for it to get compiled.  Is that not the case, and do you recommend a C hook?  It'd save me some benchmarking if you can point me one way or the other.

Another question for later: is the timing measurement error for a profiler likely to change for VM and JITed code?  That is, there's a delay before I get to call os.clock or equivalent on entering the hook, and after calling it on leaving.  One day, it might be nice to estimate that.  It'll be different for Lua and LuaJIT but that's fine because it'll have to be estimated at run-time anyway, but two different values for LuaJIT will be tricky.  If it is likely to be different, can a hook tell if it's been called from the VM or assembler?

> But note that the Lua debug interface is rather brittle, anyway.
> It mixes too many different concerns, it's not designed to be
> extensible, it works at the wrong abstraction level and it's
> incomplete (doesn't report yields, errors). It may work for simple
> tasks, but a full-blown debugger or trace analyzer needs way too
> much guesswork and workarounds.

I'm just tracing calls and lines, not recording variable values so I haven't even looked at getlocal or getupvalue , but I've implemented a few workarounds, and they rely on yield, resume, pcall, xpcall and error keeping their names, and make the assumption that any call to a C function could be a wrapped coroutine.  Even for resume you can't be sure that you're switching threads, because if the thread is finished, nothing happens.

I'm not sure what you mean by "wrong abstraction level".  I guess I just haven't thought about it.

> Even setting a simple breakpoint is excessively complicated.

Haven't tried that :-)

> In other words: design a new and better API for debuggers/profilers
> and I might implement it. Or investigate ways to use existing
> debug protocols (stepping through bytecode in GDB -- why not?).

At the moment I'm just trying make a very simple tracer that doesn't require too much extra infrastructure, so GDB might be out of scope (and a lot for me to learn).  But I'm happy to share what I am learning and see if someone more qualified can design things around that.

Cheers,
Geoff