authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-08-28 18:06:35-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-08-28 18:07:13-07:00
log13b5cee4cce2be7b5d1423fcd59b00ff1807142e
tree18102a8fd19ea54f1049ba6a0be522391a2bb7c7
parentc81219c573f75a2163dfaae5bae7d7373e179f91

fuzzing: fix entry address logic

* the pcs list is unsorted * use the function address Fixes entry points in ReleaseSafe mode.

2 files changed, 12 insertions(+), 8 deletions(-)

lib/compiler/test_runner.zig+1-2
......@@ -166,6 +166,7 @@ fn mainServer() !void {
166166 if (log_err_count != 0) @panic("error logs detected");
167167 if (first) {
168168 first = false;
169 const entry_addr = @intFromPtr(test_fn.func);
169170 try server.serveU64Message(.fuzz_start_addr, entry_addr);
170171 }
171172 }
......@@ -347,7 +348,6 @@ const FuzzerSlice = extern struct {
347348};
348349
349350var is_fuzz_test: bool = undefined;
350var entry_addr: usize = 0;
351351
352352extern fn fuzzer_next() FuzzerSlice;
353353extern fn fuzzer_init(cache_dir: FuzzerSlice) void;
......@@ -358,7 +358,6 @@ pub fn fuzzInput(options: testing.FuzzInputOptions) []const u8 {
358358 if (crippled) return "";
359359 is_fuzz_test = true;
360360 if (builtin.fuzz) {
361 if (entry_addr == 0) entry_addr = @returnAddress();
362361 return fuzzer_next().toSlice();
363362 }
364363 if (options.corpus.len == 0) return "";
lib/std/Build/Fuzz/WebServer.zig+11-6
......@@ -664,11 +664,16 @@ fn addEntryPoint(ws: *WebServer, coverage_id: u64, addr: u64) error{ AlreadyRepo
664664 const coverage_map = ws.coverage_files.getPtr(coverage_id).?;
665665 const header: *const abi.SeenPcsHeader = @ptrCast(coverage_map.mapped_memory[0..@sizeOf(abi.SeenPcsHeader)]);
666666 const pcs = header.pcAddrs();
667 const index = std.sort.upperBound(usize, pcs, addr, struct {
668 fn order(context: usize, item: usize) std.math.Order {
669 return std.math.order(item, context);
667 // Since this pcs list is unsorted, we must linear scan for the best index.
668 const index = i: {
669 var best: usize = 0;
670 for (pcs[1..], 1..) |elem_addr, i| {
671 if (elem_addr == addr) break :i i;
672 if (elem_addr > addr) continue;
673 if (elem_addr > pcs[best]) best = i;
670674 }
671 }.order);
675 break :i best;
676 };
672677 if (index >= pcs.len) {
673678 log.err("unable to find unit test entry address 0x{x} in source locations (range: 0x{x} to 0x{x})", .{
674679 addr, pcs[0], pcs[pcs.len - 1],
......@@ -678,8 +683,8 @@ fn addEntryPoint(ws: *WebServer, coverage_id: u64, addr: u64) error{ AlreadyRepo
678683 if (false) {
679684 const sl = coverage_map.source_locations[index];
680685 const file_name = coverage_map.coverage.stringAt(coverage_map.coverage.fileAt(sl.file).basename);
681 log.debug("server found entry point for 0x{x} at {s}:{d}:{d}", .{
682 addr, file_name, sl.line, sl.column,
686 log.debug("server found entry point for 0x{x} at {s}:{d}:{d} - index {d} between {x} and {x}", .{
687 addr, file_name, sl.line, sl.column, index, pcs[index - 1], pcs[index + 1],
683688 });
684689 }
685690 const gpa = ws.gpa;