Commit 4e32edbff5
Changed files (3)
lib
std
Build
lib/std/Build/Fuzz/abi.zig
@@ -8,12 +8,19 @@
///
/// Trailing:
/// * pc_addr: usize for each pcs_len
-/// * 1 bit per pc_addr, usize elements
+/// * 1 bit per pc_addr, u8 elements
pub const SeenPcsHeader = extern struct {
n_runs: usize,
unique_runs: usize,
pcs_len: usize,
lowest_stack: usize,
+
+ /// Used for comptime assertions. Provides a mechanism for strategically
+ /// causing compile errors.
+ pub const trailing = .{
+ .pc_addr,
+ .{ .pc_bits, u8 },
+ };
};
pub const ToClientTag = enum(u8) {
lib/std/Build/Fuzz/WebServer.zig
@@ -7,6 +7,7 @@ const Step = std.Build.Step;
const Coverage = std.debug.Coverage;
const abi = std.Build.Fuzz.abi;
const log = std.log;
+const assert = std.debug.assert;
const WebServer = @This();
@@ -383,7 +384,10 @@ fn sendCoverageContext(
// TODO: make each events URL correspond to one coverage map
const coverage_map = &coverage_maps[0];
const cov_header: *const abi.SeenPcsHeader = @ptrCast(coverage_map.mapped_memory[0..@sizeOf(abi.SeenPcsHeader)]);
+ comptime assert(abi.SeenPcsHeader.trailing[0] == .pc_addr);
const seen_pcs = coverage_map.mapped_memory[@sizeOf(abi.SeenPcsHeader) + coverage_map.source_locations.len * @sizeOf(usize) ..];
+ comptime assert(abi.SeenPcsHeader.trailing[1][0] == .pc_bits);
+ comptime assert(abi.SeenPcsHeader.trailing[1][1] == u8);
const n_runs = @atomicLoad(usize, &cov_header.n_runs, .monotonic);
const unique_runs = @atomicLoad(usize, &cov_header.unique_runs, .monotonic);
const lowest_stack = @atomicLoad(usize, &cov_header.lowest_stack, .monotonic);
@@ -630,6 +634,7 @@ fn prepareTables(
gop.value_ptr.mapped_memory = mapped_memory;
const header: *const abi.SeenPcsHeader = @ptrCast(mapped_memory[0..@sizeOf(abi.SeenPcsHeader)]);
+ comptime assert(abi.SeenPcsHeader.trailing[0] == .pc_addr);
const pcs_bytes = mapped_memory[@sizeOf(abi.SeenPcsHeader)..][0 .. header.pcs_len * @sizeOf(usize)];
const pcs = std.mem.bytesAsSlice(usize, pcs_bytes);
const source_locations = try gpa.alloc(Coverage.SourceLocation, pcs.len);
@@ -649,6 +654,7 @@ fn addEntryPoint(ws: *WebServer, coverage_id: u64, addr: u64) error{ AlreadyRepo
const coverage_map = ws.coverage_files.getPtr(coverage_id).?;
const ptr = coverage_map.mapped_memory;
+ comptime assert(abi.SeenPcsHeader.trailing[0] == .pc_addr);
const pcs_bytes = ptr[@sizeOf(abi.SeenPcsHeader)..][0 .. coverage_map.source_locations.len * @sizeOf(usize)];
const pcs: []const usize = @alignCast(std.mem.bytesAsSlice(usize, pcs_bytes));
const index = std.sort.upperBound(usize, pcs, addr, struct {
lib/fuzzer.zig
@@ -214,6 +214,9 @@ const Fuzzer = struct {
});
defer coverage_file.close();
const n_bitset_elems = (flagged_pcs.len + 7) / 8;
+ comptime assert(SeenPcsHeader.trailing[0] == .pc_addr);
+ comptime assert(SeenPcsHeader.trailing[1][0] == .pc_bits);
+ comptime assert(SeenPcsHeader.trailing[1][1] == u8);
const bytes_len = @sizeOf(SeenPcsHeader) + flagged_pcs.len * @sizeOf(usize) + n_bitset_elems;
const existing_len = coverage_file.getEndPos() catch |err| {
fatal("unable to check len of coverage file: {s}", .{@errorName(err)});
@@ -301,6 +304,10 @@ const Fuzzer = struct {
// Track code coverage from all runs.
{
+ comptime assert(SeenPcsHeader.trailing[0] == .pc_addr);
+ comptime assert(SeenPcsHeader.trailing[1][0] == .pc_bits);
+ comptime assert(SeenPcsHeader.trailing[1][1] == u8);
+
const seen_pcs = f.seen_pcs.items[@sizeOf(SeenPcsHeader) + f.flagged_pcs.len * @sizeOf(usize) ..];
for (seen_pcs, 0..) |*elem, i| {
const byte_i = i * 8;