Closed daurnimator closed 8 years ago
luacov patches global coroutine.create and coroutine.wrap so that coroutines they produce have the debug hook on. So it should just work unless a module uses these functions before luacov module is loaded or coroutines are created using C API.
Thats good to know.
However, in my case, the coroutines are being created in C. What should I do?
Assuming you control coroutine creation or can access all coroutines created from C, you could get the debug hook luacov uses using debug.gethook on the main thread, then set it on each coroutine. Perhaps luacov should expose a function for that...
To be more specific, I'm trying to profile some code that uses cqueues.
The cq:wrap
method takes a function, turns it into a coroutine, adds it to the scheduler cq
.
https://github.com/wahern/cqueues/blob/faa63dc4593c6ce8c7774a6f0e8bc583b18ebbd4/src/cqueues.c#L2331
How could/should this function be changed to be "luacov friendly"?
In PUC-Rio Lua, debug hooks are per-coroutine
And it isn't it so in LuaJIT? (I wasn't aware!) Maybe the simplest thing is just to test coverage using that instead?
And it isn't it so in LuaJIT? (I wasn't aware!)
From http://luajit.org/status.html: "The Lua debug API is missing a couple of features (return hooks for non-Lua functions) and shows slightly different behavior in LuaJIT (no per-coroutine hooks, no tail call counting)."
Maybe the simples thing is just to test coverage using that instead?
Not when my code uses 5.3 features :)
@daurnimator you could get debug hook in the main chunk and set it in the beginning of functions passed to cq:wrap():
local hook, mask = debug.gethook()
...
cq:wrap(function() debug.sethook(hook, mask) ... end)
@daurnimator you could get debug hook in the main chunk and set it in the beginning of functions passed to cq:wrap():
Interesting..... but hard to place into a library.
I'm wondering if there's a reasonable place to put something like this:
if not jit then -- LuaJIT does not support per-coroutine debug hooks
local wrap; wrap = cqueues.interpose("wrap", function (self, func, ...)
local hook, mask, count = debug.gethook()
return wrap(self, function (...)
debug.sethook(hook, mask, count)
return func(...)
end, ...)
end)
end
(interpose
is a method provided on cqueues objects for extending the class)
BTW, this whole issue is something I brought up with Roberto in stockholm: having something like luai_userstatethread
that you can provide via the debug library.
@daurnimator a minor issue with that approach is that the debug.sethook call itself isn't covered. Perhaps luacov should expose a wrapper function instead, e.g.
if not jit then -- LuaJIT does not support per-coroutine debug hooks
local wrap; wrap = cqueues.interpose("wrap", function(self, func, ...)
func = luacov.runner.with_luacov(func)
return wrap(self, func, ...)
end)
end
Perhaps the luajit check should be in luacov?
@daurnimator sure, that would make sense
@daurnimator under LuaJIT on master branch luacov now doesn't patch coroutine functions and in #42 with_luacov() doesn't call debug.sethook.
Thanks. that's helpful.
How can/should I use luacov with coroutine heavy programs? (In PUC-Rio Lua, debug hooks are per-coroutine)