Open mschwager opened 7 months ago
I think making this functionality public and officially supported would help too: https://github.com/ruby/ruby/blob/v3_3_0/include/ruby/debug.h#L774-L792.
Upstream feature request here: https://bugs.ruby-lang.org/issues/20448
Ruzzy implements libFuzzer's SanitizerCoverage to achieve coverage-guided fuzzing of Ruby code.
It achieves this via three of SanitizerCoverage's features:
To implement counters and the pc-table, Ruzzy hooks coverage events similar to Ruby's builtin Coverage module. It's great that this functionality is built into Ruby and we don't have to modify the Ruby bytecode during execution, or use some other heavy-handed means of tracking coverage. However, coverage instrumentation is not currently part of Ruby's public C API. To gather coverage instrumentation, Ruzzy has to perform two hacky actions:
Hook the internal-only
RUBY_EVENT_COVERAGE_BRANCH
event:https://github.com/trailofbits/ruzzy/blob/5e399440559ec397a008ae271c0c78edd628cef5/ext/cruzzy/cruzzy.c#L12-L16
Call the Ruby interface to the
Coverage
module to enable coverage tracking, rather than a public C API:https://github.com/trailofbits/ruzzy/blob/5e399440559ec397a008ae271c0c78edd628cef5/ext/cruzzy/cruzzy.c#L195-L211
As the comment mentions, we must call
Coverage.setup
, which callsrb_set_coverages
. If this is not called, thenrb_get_coverages
will returnNULL
iniseq.c
, and coverage tracking will not be enabled.To simplify Ruzzy's coverage tracking, I would request that both of these pieces of functionality be made a part of Ruby's public C interface. Particularly, the
RUBY_EVENT_COVERAGE_BRANCH
event, so we can hook coverage events with the standardrb_add_event_hook
function. And a means to initialize Ruby's global coverage state, similar torb_set_coverages
, so a C extension can enable and gather coverage information. It would be very helpful if coverage events like lines and branches were added to theTracePoint
API, both for Ruby and for C extensions.An additional nice to have would be extending the public
tracearg
functionality to include additional coverage information. Currently,tracearg
offers information likerb_tracearg_lineno
andrb_tracearg_path
. It would be helpful if it also provided additional coverage information likecoverage.c
's column information and a unique identifier for each branch. Currently, Ruzzy has to use(path, lineno)
as a unique identifier for a branch because that's what's offered by the public API, but more information would be helpful for uniquely identify branches.