From 13b5cee4cce2be7b5d1423fcd59b00ff1807142e Mon Sep 17 00:00:00 2001 From: Andrew Kelley Date: Wed, 28 Aug 2024 18:06:35 -0700 Subject: [PATCH] fuzzing: fix entry address logic * the pcs list is unsorted * use the function address Fixes entry points in ReleaseSafe mode. --- lib/compiler/test_runner.zig | 3 +-- lib/std/Build/Fuzz/WebServer.zig | 17 +++++++++++------ 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/lib/compiler/test_runner.zig b/lib/compiler/test_runner.zig index 836f70f931..ac9629a57d 100644 --- a/lib/compiler/test_runner.zig +++ b/lib/compiler/test_runner.zig @@ -166,6 +166,7 @@ fn mainServer() !void { if (log_err_count != 0) @panic("error logs detected"); if (first) { first = false; + const entry_addr = @intFromPtr(test_fn.func); try server.serveU64Message(.fuzz_start_addr, entry_addr); } } @@ -347,7 +348,6 @@ const FuzzerSlice = extern struct { }; var is_fuzz_test: bool = undefined; -var entry_addr: usize = 0; extern fn fuzzer_next() FuzzerSlice; extern fn fuzzer_init(cache_dir: FuzzerSlice) void; @@ -358,7 +358,6 @@ pub fn fuzzInput(options: testing.FuzzInputOptions) []const u8 { if (crippled) return ""; is_fuzz_test = true; if (builtin.fuzz) { - if (entry_addr == 0) entry_addr = @returnAddress(); return fuzzer_next().toSlice(); } if (options.corpus.len == 0) return ""; diff --git a/lib/std/Build/Fuzz/WebServer.zig b/lib/std/Build/Fuzz/WebServer.zig index 26b25b83d9..a0ab018cf5 100644 --- a/lib/std/Build/Fuzz/WebServer.zig +++ b/lib/std/Build/Fuzz/WebServer.zig @@ -664,11 +664,16 @@ fn addEntryPoint(ws: *WebServer, coverage_id: u64, addr: u64) error{ AlreadyRepo const coverage_map = ws.coverage_files.getPtr(coverage_id).?; const header: *const abi.SeenPcsHeader = @ptrCast(coverage_map.mapped_memory[0..@sizeOf(abi.SeenPcsHeader)]); const pcs = header.pcAddrs(); - const index = std.sort.upperBound(usize, pcs, addr, struct { - fn order(context: usize, item: usize) std.math.Order { - return std.math.order(item, context); + // Since this pcs list is unsorted, we must linear scan for the best index. + const index = i: { + var best: usize = 0; + for (pcs[1..], 1..) |elem_addr, i| { + if (elem_addr == addr) break :i i; + if (elem_addr > addr) continue; + if (elem_addr > pcs[best]) best = i; } - }.order); + break :i best; + }; if (index >= pcs.len) { log.err("unable to find unit test entry address 0x{x} in source locations (range: 0x{x} to 0x{x})", .{ addr, pcs[0], pcs[pcs.len - 1], @@ -678,8 +683,8 @@ fn addEntryPoint(ws: *WebServer, coverage_id: u64, addr: u64) error{ AlreadyRepo if (false) { const sl = coverage_map.source_locations[index]; const file_name = coverage_map.coverage.stringAt(coverage_map.coverage.fileAt(sl.file).basename); - log.debug("server found entry point for 0x{x} at {s}:{d}:{d}", .{ - addr, file_name, sl.line, sl.column, + log.debug("server found entry point for 0x{x} at {s}:{d}:{d} - index {d} between {x} and {x}", .{ + addr, file_name, sl.line, sl.column, index, pcs[index - 1], pcs[index + 1], }); } const gpa = ws.gpa;