feat(coverage): Go-side line coverage built on the debug hook (LCOV) - #1
Closed
xepozz wants to merge 1 commit into
Closed
feat(coverage): Go-side line coverage built on the debug hook (LCOV)#1xepozz wants to merge 1 commit into
xepozz wants to merge 1 commit into
Conversation
Coverage is a consumer of the debug hook (this branch is based on the sethook/gethook branch), not a separate instrumentation path: - WIPPY_COVERAGE arms every LState's line hook via covArm (hookMask |= HookMaskLine) in newLState — no debug.sethook call needed, no separate dispatch-loop guard; - the hook's line-event path in callHook records each executing source line (numerator), reusing the hook's hookLastLine dedup; - CompileWithOptions registers every prototype's coverable lines (walking nested FunctionPrototypes' DbgSourcePositions) = exact denominator incl. never-run functions; - WriteCoverageLCOV / CoverageSummary emit a standard LCOV tracefile. No-op when WIPPY_COVERAGE is unset (covArm and covRegisterProto both bail). Full suite green, go vet clean; smoke confirms covArm arms the hook and hits are recorded with no explicit sethook.
Owner
Author
|
Moving to upstream wippyai/go-lua. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds an opt-in line-coverage collector that emits a standard LCOV tracefile.
It is a consumer of the debug hook from wippyai#34, not a separate instrumentation path.
Enable by setting
WIPPY_COVERAGEin the environment before the process starts.The host then calls
WriteCoverageLCOV(path, filter)to write the report.Why
Line hooks are the primitive every Lua coverage tool is built on. wippyai#34 adds the
hook; this PR turns it into a working coverage collector that spans a whole
embedding — every
LState, including coroutine/child threads — which is awkwardto achieve with pure-Lua
debug.sethookwiring in a host that spawns many states.Design
coverage.go(new) — the collector:covArm,covRecordHit,covRegisterProto,WriteCoverageLCOV,CoverageSummary,CoverageEnabled.WIPPY_COVERAGEis set,covArmarms every newLStatewith a line hook (hookMask |= HookMaskLine) —no
debug.sethookcall needed. The hook's existing line-event path incallHookrecords the executing source line, reusing itshookLastLinededup.covArmis wired into bothnewLStateandnewLStateWithGlobal(thecoroutine/thread constructor), so child states are covered too.
CompileWithOptionsregisters everyprototype's
DbgSourcePositions, walking nestedFunctionPrototypes— so thedenominator includes never-executed functions, not just lines that ran.
WriteCoverageLCOV(path, filter)emitsSF/DA/LF/LH/end_of_record;CoverageSummary(filter)returns aggregate(found, hit). Collection isprocess-global (merged across all
LStates), so a host that runs many states orcoroutines gets a single report — dump it once at shutdown.
Usage
Source names in
SF:are the chunk names you pass toLoad/LoadString(e.g.
@path/to/file.lua), so the filter selects which chunks land in the report.Example output:
coverage.infois consumed as-is bygenhtml, Codecov/Coveralls, and editorcoverage plugins.
Performance
Zero hot-path cost when disabled:
covArmandcovRegisterProtobail immediatelyunless
WIPPY_COVERAGEis set, and the dispatch loop uses the hook's existingif L.hookMask != 0guard (from wippyai#34) — no additional per-instruction check. Withno hook installed and
WIPPY_COVERAGEunset, none of this runs.Scope of changes
coverage.go(new) + one line incallHook(hook.go), thecovArmcalls instate.go/state_pool.go, and onecovRegisterProtocall incompile_options.go. No generated files touched.Verification
go vetclean.and coroutines, running a workload under
WIPPY_COVERAGE, and confirming theemitted LCOV parses cleanly in
genhtmland reports plausible per-file linecoverage. A regression where coroutine/child-thread states were left unarmed
(recording only part of the executed lines) is fixed by arming
newLStateWithGlobal.Note for maintainers
This is opinionated tooling rather than a Lua-language feature. If you'd prefer to
keep coverage out of the core, I'm happy to gate it behind a build tag
(
//go:build coverage) or maintain it as a fork — just let me know.