fuzzing: fix entry address logic

* the pcs list is unsorted
* use the function address

Fixes entry points in ReleaseSafe mode.
This commit is contained in:
Andrew Kelley 2024-08-28 18:06:35 -07:00
parent c81219c573
commit 13b5cee4cc
2 changed files with 12 additions and 8 deletions

View File

@ -166,6 +166,7 @@ fn mainServer() !void {
if (log_err_count != 0) @panic("error logs detected"); if (log_err_count != 0) @panic("error logs detected");
if (first) { if (first) {
first = false; first = false;
const entry_addr = @intFromPtr(test_fn.func);
try server.serveU64Message(.fuzz_start_addr, entry_addr); try server.serveU64Message(.fuzz_start_addr, entry_addr);
} }
} }
@ -347,7 +348,6 @@ const FuzzerSlice = extern struct {
}; };
var is_fuzz_test: bool = undefined; var is_fuzz_test: bool = undefined;
var entry_addr: usize = 0;
extern fn fuzzer_next() FuzzerSlice; extern fn fuzzer_next() FuzzerSlice;
extern fn fuzzer_init(cache_dir: FuzzerSlice) void; extern fn fuzzer_init(cache_dir: FuzzerSlice) void;
@ -358,7 +358,6 @@ pub fn fuzzInput(options: testing.FuzzInputOptions) []const u8 {
if (crippled) return ""; if (crippled) return "";
is_fuzz_test = true; is_fuzz_test = true;
if (builtin.fuzz) { if (builtin.fuzz) {
if (entry_addr == 0) entry_addr = @returnAddress();
return fuzzer_next().toSlice(); return fuzzer_next().toSlice();
} }
if (options.corpus.len == 0) return ""; if (options.corpus.len == 0) return "";

View File

@ -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 coverage_map = ws.coverage_files.getPtr(coverage_id).?;
const header: *const abi.SeenPcsHeader = @ptrCast(coverage_map.mapped_memory[0..@sizeOf(abi.SeenPcsHeader)]); const header: *const abi.SeenPcsHeader = @ptrCast(coverage_map.mapped_memory[0..@sizeOf(abi.SeenPcsHeader)]);
const pcs = header.pcAddrs(); const pcs = header.pcAddrs();
const index = std.sort.upperBound(usize, pcs, addr, struct { // Since this pcs list is unsorted, we must linear scan for the best index.
fn order(context: usize, item: usize) std.math.Order { const index = i: {
return std.math.order(item, context); 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) { if (index >= pcs.len) {
log.err("unable to find unit test entry address 0x{x} in source locations (range: 0x{x} to 0x{x})", .{ 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], addr, pcs[0], pcs[pcs.len - 1],
@ -678,8 +683,8 @@ fn addEntryPoint(ws: *WebServer, coverage_id: u64, addr: u64) error{ AlreadyRepo
if (false) { if (false) {
const sl = coverage_map.source_locations[index]; const sl = coverage_map.source_locations[index];
const file_name = coverage_map.coverage.stringAt(coverage_map.coverage.fileAt(sl.file).basename); 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}", .{ 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, addr, file_name, sl.line, sl.column, index, pcs[index - 1], pcs[index + 1],
}); });
} }
const gpa = ws.gpa; const gpa = ws.gpa;