feature. See also
. The project being documented here (as the example) is the Zig library itself.
Fuzz.sendUpdate
pub fn sendUpdate(
fuzz: *Fuzz,
socket: *std.http.Server.WebSocket,
prev: *Previous,
) !void
File
Code
pub fn sendUpdate(
fuzz: *Fuzz,
socket: *std.http.Server.WebSocket,
prev: *Previous,
) !void {
const maker = fuzz.maker;
const graph = maker.graph;
const io = graph.io;
try fuzz.coverage_mutex.lock(io);
defer fuzz.coverage_mutex.unlock(io);
const coverage_maps = fuzz.coverage_files.values();
if (coverage_maps.len == 0) return;
const coverage_map = &coverage_maps[0];
const cov_header: *const abi.SeenPcsHeader = @ptrCast(coverage_map.mapped_memory[0..@sizeOf(abi.SeenPcsHeader)]);
// buffer off to the kernel, because we might race with the fuzzer process[es]. This brings the
// whole mmap strategy into question. Incidentally, I wonder if post-writergate we could pass
// this data straight to the socket with sendfile...
const seen_pcs = cov_header.seenBits();
const n_runs = @atomicLoad(usize, &cov_header.n_runs, .monotonic);
const unique_runs = @atomicLoad(usize, &cov_header.unique_runs, .monotonic);
{
if (!prev.sent_source_index) {
prev.sent_source_index = true;
const header: abi.SourceIndexHeader = .{
.directories_len = @intCast(coverage_map.coverage.directories.entries.len),
.files_len = @intCast(coverage_map.coverage.files.entries.len),
.source_locations_len = @intCast(coverage_map.source_locations.len),
.string_bytes_len = @intCast(coverage_map.coverage.string_bytes.items.len),
.start_timestamp = coverage_map.start_timestamp,
.start_n_runs = coverage_map.start_n_runs,
};
var iovecs: [5][]const u8 = .{
@ptrCast(&header),
@ptrCast(coverage_map.coverage.directories.keys()),
@ptrCast(coverage_map.coverage.files.keys()),
@ptrCast(coverage_map.source_locations),
coverage_map.coverage.string_bytes.items,
};
try socket.writeMessageVec(&iovecs, .binary);
}
const header: abi.CoverageUpdateHeader = .{
.n_runs = n_runs,
.unique_runs = unique_runs,
};
var iovecs: [2][]const u8 = .{
@ptrCast(&header),
@ptrCast(seen_pcs),
};
try socket.writeMessageVec(&iovecs, .binary);
prev.unique_runs = unique_runs;
}
if (prev.entry_points != coverage_map.entry_points.items.len) {
const header: abi.EntryPointHeader = .init(@intCast(coverage_map.entry_points.items.len));
var iovecs: [2][]const u8 = .{
@ptrCast(&header),
@ptrCast(coverage_map.entry_points.items),
};
try socket.writeMessageVec(&iovecs, .binary);
prev.entry_points = coverage_map.entry_points.items.len;
}
}