Skip to content

Commit 9bb0b43

Browse files
committed
implement review suggestions
1 parent 0feacc2 commit 9bb0b43

File tree

5 files changed

+56
-78
lines changed

5 files changed

+56
-78
lines changed

lib/compiler/build_runner.zig

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -280,21 +280,21 @@ pub fn main() !void {
280280
}
281281
} else if (mem.startsWith(u8, arg, "--fuzz=")) {
282282
const value = arg["--fuzz=".len..];
283-
if (value.len == 0) fatal("missing argument to --fuzz\n", .{});
283+
if (value.len == 0) fatal("missing argument to --fuzz", .{});
284284

285285
const unit: u8 = value[value.len - 1];
286-
const digits = switch (value[value.len - 1]) {
286+
const digits = switch (unit) {
287287
'0'...'9' => value,
288288
'K', 'M', 'G' => value[0 .. value.len - 1],
289289
else => fatal(
290-
"invalid argument to --fuzz, expected a positive number optionally suffixed by one of: [KMG]\n",
290+
"invalid argument to --fuzz, expected a positive number optionally suffixed by one of: [KMG]",
291291
.{},
292292
),
293293
};
294294

295295
const amount = std.fmt.parseInt(u64, digits, 10) catch {
296296
fatal(
297-
"invalid argument to --fuzz, expected a positive number optionally suffixed by one of: [KMG]\n",
297+
"invalid argument to --fuzz, expected a positive number optionally suffixed by one of: [KMG]",
298298
.{},
299299
);
300300
};
@@ -305,7 +305,7 @@ pub fn main() !void {
305305
'K' => 1000,
306306
'M' => 1_000_000,
307307
'G' => 1_000_000_000,
308-
}) catch fatal("fuzzing limit amount overflows u64\n", .{});
308+
}) catch fatal("fuzzing limit amount overflows u64", .{});
309309

310310
fuzz = .{
311311
.limit = .{
@@ -520,7 +520,11 @@ pub fn main() !void {
520520
};
521521

522522
if (run.web_server) |*web_server| {
523-
if (fuzz) |mode| assert(mode == .forever);
523+
if (fuzz) |mode| if (mode != .forever) fatal(
524+
"error: limited fuzzing is not implemented yet for --webui",
525+
.{},
526+
);
527+
524528
web_server.finishBuild(.{ .fuzz = fuzz != null });
525529
}
526530

lib/compiler/test_runner.zig

Lines changed: 17 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -56,20 +56,21 @@ pub fn main() void {
5656
}
5757
}
5858

59-
fba.reset();
6059
if (builtin.fuzz) {
6160
const cache_dir = opt_cache_dir orelse @panic("missing --cache-dir=[path] argument");
6261
fuzz_abi.fuzzer_init(.fromSlice(cache_dir));
6362
}
6463

64+
fba.reset();
65+
6566
if (listen) {
66-
return mainServer(opt_cache_dir) catch @panic("internal test runner failure");
67+
return mainServer() catch @panic("internal test runner failure");
6768
} else {
6869
return mainTerminal();
6970
}
7071
}
7172

72-
fn mainServer(opt_cache_dir: ?[]const u8) !void {
73+
fn mainServer() !void {
7374
@disableInstrumentation();
7475
var stdin_reader = std.fs.File.stdin().readerStreaming(&stdin_buffer);
7576
var stdout_writer = std.fs.File.stdout().writerStreaming(&stdout_buffer);
@@ -79,66 +80,14 @@ fn mainServer(opt_cache_dir: ?[]const u8) !void {
7980
.zig_version = builtin.zig_version_string,
8081
});
8182

82-
if (builtin.fuzz) blk: {
83-
const cache_dir = opt_cache_dir.?;
84-
const coverage_id = fuzz_abi.fuzzer_coverage_id();
85-
const coverage_file_path: std.Build.Cache.Path = .{
86-
.root_dir = .{
87-
.path = cache_dir,
88-
.handle = std.fs.cwd().openDir(cache_dir, .{}) catch |err| {
89-
if (err == error.FileNotFound) {
90-
try server.serveCoverageIdMessage(coverage_id, 0, 0, 0);
91-
break :blk;
92-
}
93-
94-
fatal("failed to access cache dir '{s}': {s}", .{
95-
cache_dir, @errorName(err),
96-
});
97-
},
98-
},
99-
.sub_path = "v/" ++ std.fmt.hex(coverage_id),
100-
};
101-
102-
var coverage_file = coverage_file_path.root_dir.handle.openFile(coverage_file_path.sub_path, .{}) catch |err| {
103-
if (err == error.FileNotFound) {
104-
try server.serveCoverageIdMessage(coverage_id, 0, 0, 0);
105-
break :blk;
106-
}
107-
108-
fatal("failed to load coverage file '{f}': {s}", .{
109-
coverage_file_path, @errorName(err),
110-
});
111-
};
112-
defer coverage_file.close();
113-
114-
var rbuf: [0x1000]u8 = undefined;
115-
var r = coverage_file.reader(&rbuf);
116-
117-
var header: fuzz_abi.SeenPcsHeader = undefined;
118-
r.interface.readSliceAll(std.mem.asBytes(&header)) catch |err| {
119-
fatal("failed to read from coverage file '{f}': {s}", .{
120-
coverage_file_path, @errorName(err),
121-
});
122-
};
123-
124-
if (header.pcs_len == 0) {
125-
fatal("corrupted coverage file '{f}': pcs_len was zero", .{
126-
coverage_file_path,
127-
});
128-
}
129-
130-
var seen_count: usize = 0;
131-
const chunk_count = fuzz_abi.SeenPcsHeader.seenElemsLen(header.pcs_len);
132-
for (0..chunk_count) |_| {
133-
const seen = r.interface.takeInt(usize, .little) catch |err| {
134-
fatal("failed to read from coverage file '{f}': {s}", .{
135-
coverage_file_path, @errorName(err),
136-
});
137-
};
138-
seen_count += @popCount(seen);
139-
}
140-
141-
try server.serveCoverageIdMessage(coverage_id, header.n_runs, header.unique_runs, seen_count);
83+
if (builtin.fuzz) {
84+
const coverage = fuzz_abi.fuzzer_coverage();
85+
try server.serveCoverageIdMessage(
86+
coverage.id,
87+
coverage.runs,
88+
coverage.unique,
89+
coverage.seen,
90+
);
14291
}
14392

14493
while (true) {
@@ -235,7 +184,7 @@ fn mainServer(opt_cache_dir: ?[]const u8) !void {
235184
if (@errorReturnTrace()) |trace| {
236185
std.debug.dumpStackTrace(trace.*);
237186
}
238-
std.debug.print("failed with error.{s}\n", .{@errorName(err)});
187+
std.debug.print("failed with error.{t}\n", .{err});
239188
std.process.exit(1);
240189
},
241190
};
@@ -305,11 +254,11 @@ fn mainTerminal() void {
305254
else => {
306255
fail_count += 1;
307256
if (have_tty) {
308-
std.debug.print("{d}/{d} {s}...FAIL ({s})\n", .{
309-
i + 1, test_fn_list.len, test_fn.name, @errorName(err),
257+
std.debug.print("{d}/{d} {s}...FAIL ({t})\n", .{
258+
i + 1, test_fn_list.len, test_fn.name, err,
310259
});
311260
} else {
312-
std.debug.print("FAIL ({s})\n", .{@errorName(err)});
261+
std.debug.print("FAIL ({t})\n", .{err});
313262
}
314263
if (@errorReturnTrace()) |trace| {
315264
std.debug.dumpStackTrace(trace.*);
@@ -450,7 +399,7 @@ pub fn fuzz(
450399
else => {
451400
std.debug.lockStdErr();
452401
if (@errorReturnTrace()) |trace| std.debug.dumpStackTrace(trace.*);
453-
std.debug.print("failed with error.{s}\n", .{@errorName(err)});
402+
std.debug.print("failed with error.{t}\n", .{err});
454403
std.process.exit(1);
455404
},
456405
};

lib/fuzzer.zig

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const builtin = @import("builtin");
22
const std = @import("std");
3+
const fatal = std.process.fatal;
34
const mem = std.mem;
45
const math = std.math;
56
const Allocator = mem.Allocator;
@@ -105,6 +106,7 @@ const Executable = struct {
105106
const coverage_file_len = @sizeOf(abi.SeenPcsHeader) +
106107
pc_bitset_usizes * @sizeOf(usize) +
107108
pcs.len * @sizeOf(usize);
109+
108110
if (populate) {
109111
defer coverage_file.lock(.shared) catch |e| panic(
110112
"failed to demote lock for coverage file '{s}': {t}",
@@ -581,8 +583,21 @@ export fn fuzzer_init(cache_dir_path: abi.Slice) void {
581583
}
582584

583585
/// Invalid until `fuzzer_init` is called.
584-
export fn fuzzer_coverage_id() u64 {
585-
return exec.pc_digest;
586+
export fn fuzzer_coverage() abi.Coverage {
587+
const coverage_id = exec.pc_digest;
588+
const header: *const abi.SeenPcsHeader = @ptrCast(@volatileCast(exec.shared_seen_pcs.items.ptr));
589+
590+
var seen_count: usize = 0;
591+
for (header.seenBits()) |chunk| {
592+
seen_count += @popCount(chunk);
593+
}
594+
595+
return .{
596+
.id = coverage_id,
597+
.runs = header.n_runs,
598+
.unique = header.unique_runs,
599+
.seen = seen_count,
600+
};
586601
}
587602

588603
/// fuzzer_init must be called beforehand

lib/std/Build/abi.zig

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ pub const Rebuild = extern struct {
140140
pub const fuzz = struct {
141141
pub const TestOne = *const fn (Slice) callconv(.c) void;
142142
pub extern fn fuzzer_init(cache_dir_path: Slice) void;
143-
pub extern fn fuzzer_coverage_id() u64;
143+
pub extern fn fuzzer_coverage() Coverage;
144144
pub extern fn fuzzer_init_test(test_one: TestOne, unit_test_name: Slice) void;
145145
pub extern fn fuzzer_new_input(bytes: Slice) void;
146146
pub extern fn fuzzer_main(limit_kind: LimitKind, amount: u64) void;
@@ -253,6 +253,16 @@ pub const fuzz = struct {
253253
return .{ .locs_len_raw = @bitCast(locs_len) };
254254
}
255255
};
256+
257+
/// Sent by lib/fuzzer to test_runner to obtain information about the
258+
/// active memory mapped input file and cumulative stats about previous
259+
/// fuzzing runs.
260+
pub const Coverage = extern struct {
261+
id: u64,
262+
runs: u64,
263+
unique: u64,
264+
seen: u64,
265+
};
256266
};
257267

258268
/// ABI bits specifically relating to the time report interface.

test/standalone/libfuzzer/main.zig

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ pub fn main() !void {
2424
abi.fuzzer_new_input(.fromSlice(""));
2525
abi.fuzzer_new_input(.fromSlice("hello"));
2626

27-
const pc_digest = abi.fuzzer_coverage_id();
27+
const pc_digest = abi.fuzzer_coverage().id;
2828
const coverage_file_path = "v/" ++ std.fmt.hex(pc_digest);
2929
const coverage_file = try cache_dir.openFile(coverage_file_path, .{});
3030
defer coverage_file.close();

0 commit comments

Comments
 (0)