mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
implement review suggestions
This commit is contained in:
parent
0feacc2b81
commit
9bb0b43ea3
@ -280,21 +280,21 @@ pub fn main() !void {
|
|||||||
}
|
}
|
||||||
} else if (mem.startsWith(u8, arg, "--fuzz=")) {
|
} else if (mem.startsWith(u8, arg, "--fuzz=")) {
|
||||||
const value = arg["--fuzz=".len..];
|
const value = arg["--fuzz=".len..];
|
||||||
if (value.len == 0) fatal("missing argument to --fuzz\n", .{});
|
if (value.len == 0) fatal("missing argument to --fuzz", .{});
|
||||||
|
|
||||||
const unit: u8 = value[value.len - 1];
|
const unit: u8 = value[value.len - 1];
|
||||||
const digits = switch (value[value.len - 1]) {
|
const digits = switch (unit) {
|
||||||
'0'...'9' => value,
|
'0'...'9' => value,
|
||||||
'K', 'M', 'G' => value[0 .. value.len - 1],
|
'K', 'M', 'G' => value[0 .. value.len - 1],
|
||||||
else => fatal(
|
else => fatal(
|
||||||
"invalid argument to --fuzz, expected a positive number optionally suffixed by one of: [KMG]\n",
|
"invalid argument to --fuzz, expected a positive number optionally suffixed by one of: [KMG]",
|
||||||
.{},
|
.{},
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
const amount = std.fmt.parseInt(u64, digits, 10) catch {
|
const amount = std.fmt.parseInt(u64, digits, 10) catch {
|
||||||
fatal(
|
fatal(
|
||||||
"invalid argument to --fuzz, expected a positive number optionally suffixed by one of: [KMG]\n",
|
"invalid argument to --fuzz, expected a positive number optionally suffixed by one of: [KMG]",
|
||||||
.{},
|
.{},
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
@ -305,7 +305,7 @@ pub fn main() !void {
|
|||||||
'K' => 1000,
|
'K' => 1000,
|
||||||
'M' => 1_000_000,
|
'M' => 1_000_000,
|
||||||
'G' => 1_000_000_000,
|
'G' => 1_000_000_000,
|
||||||
}) catch fatal("fuzzing limit amount overflows u64\n", .{});
|
}) catch fatal("fuzzing limit amount overflows u64", .{});
|
||||||
|
|
||||||
fuzz = .{
|
fuzz = .{
|
||||||
.limit = .{
|
.limit = .{
|
||||||
@ -520,7 +520,11 @@ pub fn main() !void {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (run.web_server) |*web_server| {
|
if (run.web_server) |*web_server| {
|
||||||
if (fuzz) |mode| assert(mode == .forever);
|
if (fuzz) |mode| if (mode != .forever) fatal(
|
||||||
|
"error: limited fuzzing is not implemented yet for --webui",
|
||||||
|
.{},
|
||||||
|
);
|
||||||
|
|
||||||
web_server.finishBuild(.{ .fuzz = fuzz != null });
|
web_server.finishBuild(.{ .fuzz = fuzz != null });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -56,20 +56,21 @@ pub fn main() void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fba.reset();
|
|
||||||
if (builtin.fuzz) {
|
if (builtin.fuzz) {
|
||||||
const cache_dir = opt_cache_dir orelse @panic("missing --cache-dir=[path] argument");
|
const cache_dir = opt_cache_dir orelse @panic("missing --cache-dir=[path] argument");
|
||||||
fuzz_abi.fuzzer_init(.fromSlice(cache_dir));
|
fuzz_abi.fuzzer_init(.fromSlice(cache_dir));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fba.reset();
|
||||||
|
|
||||||
if (listen) {
|
if (listen) {
|
||||||
return mainServer(opt_cache_dir) catch @panic("internal test runner failure");
|
return mainServer() catch @panic("internal test runner failure");
|
||||||
} else {
|
} else {
|
||||||
return mainTerminal();
|
return mainTerminal();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn mainServer(opt_cache_dir: ?[]const u8) !void {
|
fn mainServer() !void {
|
||||||
@disableInstrumentation();
|
@disableInstrumentation();
|
||||||
var stdin_reader = std.fs.File.stdin().readerStreaming(&stdin_buffer);
|
var stdin_reader = std.fs.File.stdin().readerStreaming(&stdin_buffer);
|
||||||
var stdout_writer = std.fs.File.stdout().writerStreaming(&stdout_buffer);
|
var stdout_writer = std.fs.File.stdout().writerStreaming(&stdout_buffer);
|
||||||
@ -79,66 +80,14 @@ fn mainServer(opt_cache_dir: ?[]const u8) !void {
|
|||||||
.zig_version = builtin.zig_version_string,
|
.zig_version = builtin.zig_version_string,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (builtin.fuzz) blk: {
|
if (builtin.fuzz) {
|
||||||
const cache_dir = opt_cache_dir.?;
|
const coverage = fuzz_abi.fuzzer_coverage();
|
||||||
const coverage_id = fuzz_abi.fuzzer_coverage_id();
|
try server.serveCoverageIdMessage(
|
||||||
const coverage_file_path: std.Build.Cache.Path = .{
|
coverage.id,
|
||||||
.root_dir = .{
|
coverage.runs,
|
||||||
.path = cache_dir,
|
coverage.unique,
|
||||||
.handle = std.fs.cwd().openDir(cache_dir, .{}) catch |err| {
|
coverage.seen,
|
||||||
if (err == error.FileNotFound) {
|
);
|
||||||
try server.serveCoverageIdMessage(coverage_id, 0, 0, 0);
|
|
||||||
break :blk;
|
|
||||||
}
|
|
||||||
|
|
||||||
fatal("failed to access cache dir '{s}': {s}", .{
|
|
||||||
cache_dir, @errorName(err),
|
|
||||||
});
|
|
||||||
},
|
|
||||||
},
|
|
||||||
.sub_path = "v/" ++ std.fmt.hex(coverage_id),
|
|
||||||
};
|
|
||||||
|
|
||||||
var coverage_file = coverage_file_path.root_dir.handle.openFile(coverage_file_path.sub_path, .{}) catch |err| {
|
|
||||||
if (err == error.FileNotFound) {
|
|
||||||
try server.serveCoverageIdMessage(coverage_id, 0, 0, 0);
|
|
||||||
break :blk;
|
|
||||||
}
|
|
||||||
|
|
||||||
fatal("failed to load coverage file '{f}': {s}", .{
|
|
||||||
coverage_file_path, @errorName(err),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
defer coverage_file.close();
|
|
||||||
|
|
||||||
var rbuf: [0x1000]u8 = undefined;
|
|
||||||
var r = coverage_file.reader(&rbuf);
|
|
||||||
|
|
||||||
var header: fuzz_abi.SeenPcsHeader = undefined;
|
|
||||||
r.interface.readSliceAll(std.mem.asBytes(&header)) catch |err| {
|
|
||||||
fatal("failed to read from coverage file '{f}': {s}", .{
|
|
||||||
coverage_file_path, @errorName(err),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
if (header.pcs_len == 0) {
|
|
||||||
fatal("corrupted coverage file '{f}': pcs_len was zero", .{
|
|
||||||
coverage_file_path,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
var seen_count: usize = 0;
|
|
||||||
const chunk_count = fuzz_abi.SeenPcsHeader.seenElemsLen(header.pcs_len);
|
|
||||||
for (0..chunk_count) |_| {
|
|
||||||
const seen = r.interface.takeInt(usize, .little) catch |err| {
|
|
||||||
fatal("failed to read from coverage file '{f}': {s}", .{
|
|
||||||
coverage_file_path, @errorName(err),
|
|
||||||
});
|
|
||||||
};
|
|
||||||
seen_count += @popCount(seen);
|
|
||||||
}
|
|
||||||
|
|
||||||
try server.serveCoverageIdMessage(coverage_id, header.n_runs, header.unique_runs, seen_count);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
@ -235,7 +184,7 @@ fn mainServer(opt_cache_dir: ?[]const u8) !void {
|
|||||||
if (@errorReturnTrace()) |trace| {
|
if (@errorReturnTrace()) |trace| {
|
||||||
std.debug.dumpStackTrace(trace.*);
|
std.debug.dumpStackTrace(trace.*);
|
||||||
}
|
}
|
||||||
std.debug.print("failed with error.{s}\n", .{@errorName(err)});
|
std.debug.print("failed with error.{t}\n", .{err});
|
||||||
std.process.exit(1);
|
std.process.exit(1);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@ -305,11 +254,11 @@ fn mainTerminal() void {
|
|||||||
else => {
|
else => {
|
||||||
fail_count += 1;
|
fail_count += 1;
|
||||||
if (have_tty) {
|
if (have_tty) {
|
||||||
std.debug.print("{d}/{d} {s}...FAIL ({s})\n", .{
|
std.debug.print("{d}/{d} {s}...FAIL ({t})\n", .{
|
||||||
i + 1, test_fn_list.len, test_fn.name, @errorName(err),
|
i + 1, test_fn_list.len, test_fn.name, err,
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
std.debug.print("FAIL ({s})\n", .{@errorName(err)});
|
std.debug.print("FAIL ({t})\n", .{err});
|
||||||
}
|
}
|
||||||
if (@errorReturnTrace()) |trace| {
|
if (@errorReturnTrace()) |trace| {
|
||||||
std.debug.dumpStackTrace(trace.*);
|
std.debug.dumpStackTrace(trace.*);
|
||||||
@ -450,7 +399,7 @@ pub fn fuzz(
|
|||||||
else => {
|
else => {
|
||||||
std.debug.lockStdErr();
|
std.debug.lockStdErr();
|
||||||
if (@errorReturnTrace()) |trace| std.debug.dumpStackTrace(trace.*);
|
if (@errorReturnTrace()) |trace| std.debug.dumpStackTrace(trace.*);
|
||||||
std.debug.print("failed with error.{s}\n", .{@errorName(err)});
|
std.debug.print("failed with error.{t}\n", .{err});
|
||||||
std.process.exit(1);
|
std.process.exit(1);
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
const builtin = @import("builtin");
|
const builtin = @import("builtin");
|
||||||
const std = @import("std");
|
const std = @import("std");
|
||||||
|
const fatal = std.process.fatal;
|
||||||
const mem = std.mem;
|
const mem = std.mem;
|
||||||
const math = std.math;
|
const math = std.math;
|
||||||
const Allocator = mem.Allocator;
|
const Allocator = mem.Allocator;
|
||||||
@ -105,6 +106,7 @@ const Executable = struct {
|
|||||||
const coverage_file_len = @sizeOf(abi.SeenPcsHeader) +
|
const coverage_file_len = @sizeOf(abi.SeenPcsHeader) +
|
||||||
pc_bitset_usizes * @sizeOf(usize) +
|
pc_bitset_usizes * @sizeOf(usize) +
|
||||||
pcs.len * @sizeOf(usize);
|
pcs.len * @sizeOf(usize);
|
||||||
|
|
||||||
if (populate) {
|
if (populate) {
|
||||||
defer coverage_file.lock(.shared) catch |e| panic(
|
defer coverage_file.lock(.shared) catch |e| panic(
|
||||||
"failed to demote lock for coverage file '{s}': {t}",
|
"failed to demote lock for coverage file '{s}': {t}",
|
||||||
@ -581,8 +583,21 @@ export fn fuzzer_init(cache_dir_path: abi.Slice) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Invalid until `fuzzer_init` is called.
|
/// Invalid until `fuzzer_init` is called.
|
||||||
export fn fuzzer_coverage_id() u64 {
|
export fn fuzzer_coverage() abi.Coverage {
|
||||||
return exec.pc_digest;
|
const coverage_id = exec.pc_digest;
|
||||||
|
const header: *const abi.SeenPcsHeader = @ptrCast(@volatileCast(exec.shared_seen_pcs.items.ptr));
|
||||||
|
|
||||||
|
var seen_count: usize = 0;
|
||||||
|
for (header.seenBits()) |chunk| {
|
||||||
|
seen_count += @popCount(chunk);
|
||||||
|
}
|
||||||
|
|
||||||
|
return .{
|
||||||
|
.id = coverage_id,
|
||||||
|
.runs = header.n_runs,
|
||||||
|
.unique = header.unique_runs,
|
||||||
|
.seen = seen_count,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
/// fuzzer_init must be called beforehand
|
/// fuzzer_init must be called beforehand
|
||||||
|
|||||||
@ -140,7 +140,7 @@ pub const Rebuild = extern struct {
|
|||||||
pub const fuzz = struct {
|
pub const fuzz = struct {
|
||||||
pub const TestOne = *const fn (Slice) callconv(.c) void;
|
pub const TestOne = *const fn (Slice) callconv(.c) void;
|
||||||
pub extern fn fuzzer_init(cache_dir_path: Slice) void;
|
pub extern fn fuzzer_init(cache_dir_path: Slice) void;
|
||||||
pub extern fn fuzzer_coverage_id() u64;
|
pub extern fn fuzzer_coverage() Coverage;
|
||||||
pub extern fn fuzzer_init_test(test_one: TestOne, unit_test_name: Slice) void;
|
pub extern fn fuzzer_init_test(test_one: TestOne, unit_test_name: Slice) void;
|
||||||
pub extern fn fuzzer_new_input(bytes: Slice) void;
|
pub extern fn fuzzer_new_input(bytes: Slice) void;
|
||||||
pub extern fn fuzzer_main(limit_kind: LimitKind, amount: u64) void;
|
pub extern fn fuzzer_main(limit_kind: LimitKind, amount: u64) void;
|
||||||
@ -253,6 +253,16 @@ pub const fuzz = struct {
|
|||||||
return .{ .locs_len_raw = @bitCast(locs_len) };
|
return .{ .locs_len_raw = @bitCast(locs_len) };
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/// Sent by lib/fuzzer to test_runner to obtain information about the
|
||||||
|
/// active memory mapped input file and cumulative stats about previous
|
||||||
|
/// fuzzing runs.
|
||||||
|
pub const Coverage = extern struct {
|
||||||
|
id: u64,
|
||||||
|
runs: u64,
|
||||||
|
unique: u64,
|
||||||
|
seen: u64,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/// ABI bits specifically relating to the time report interface.
|
/// ABI bits specifically relating to the time report interface.
|
||||||
|
|||||||
@ -24,7 +24,7 @@ pub fn main() !void {
|
|||||||
abi.fuzzer_new_input(.fromSlice(""));
|
abi.fuzzer_new_input(.fromSlice(""));
|
||||||
abi.fuzzer_new_input(.fromSlice("hello"));
|
abi.fuzzer_new_input(.fromSlice("hello"));
|
||||||
|
|
||||||
const pc_digest = abi.fuzzer_coverage_id();
|
const pc_digest = abi.fuzzer_coverage().id;
|
||||||
const coverage_file_path = "v/" ++ std.fmt.hex(pc_digest);
|
const coverage_file_path = "v/" ++ std.fmt.hex(pc_digest);
|
||||||
const coverage_file = try cache_dir.openFile(coverage_file_path, .{});
|
const coverage_file = try cache_dir.openFile(coverage_file_path, .{});
|
||||||
defer coverage_file.close();
|
defer coverage_file.close();
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user