| ... | ... | @@ -512,7 +512,7 @@ const Fuzzer = struct { |
| 512 | 512 | self.corpus_pos = 0; |
| 513 | 513 | |
| 514 | 514 | const rng = self.rng.random(); |
| 515 | | while (true) { |
| 515 | const m = while (true) { |
| 516 | 516 | const m = self.mutations.items[rng.uintLessThanBiased(usize, self.mutations.items.len)]; |
| 517 | 517 | if (!m.mutate( |
| 518 | 518 | rng, |
| ... | ... | @@ -524,53 +524,53 @@ const Fuzzer = struct { |
| 524 | 524 | inst.const_vals8.items, |
| 525 | 525 | inst.const_vals16.items, |
| 526 | 526 | )) continue; |
| 527 | break m; |
| 528 | }; |
| 527 | 529 | |
| 528 | | self.run(); |
| 529 | | if (inst.isFresh()) { |
| 530 | | @branchHint(.unlikely); |
| 531 | | |
| 532 | | const header = mem.bytesAsValue( |
| 533 | | abi.SeenPcsHeader, |
| 534 | | exec.shared_seen_pcs.items[0..@sizeOf(abi.SeenPcsHeader)], |
| 535 | | ); |
| 536 | | _ = @atomicRmw(usize, &header.unique_runs, .Add, 1, .monotonic); |
| 530 | self.run(); |
| 537 | 531 | |
| 538 | | inst.setFresh(); |
| 539 | | self.minimizeInput(); |
| 540 | | inst.updateSeen(); |
| 541 | | |
| 542 | | // An empty-input has always been tried, so if an empty input is fresh then the |
| 543 | | // test has to be non-deterministic. This has to be checked as duplicate empty |
| 544 | | // entries are not allowed. |
| 545 | | if (self.input.items.len - 8 == 0) { |
| 546 | | std.log.warn("non-deterministic test (empty input produces different hits)", .{}); |
| 547 | | _ = @atomicRmw(usize, &header.unique_runs, .Sub, 1, .monotonic); |
| 548 | | return; |
| 549 | | } |
| 532 | if (inst.isFresh()) { |
| 533 | @branchHint(.unlikely); |
| 550 | 534 | |
| 551 | | const arena = self.arena_ctx.allocator(); |
| 552 | | const bytes = arena.dupe(u8, @volatileCast(self.input.items[8..])) catch @panic("OOM"); |
| 553 | | |
| 554 | | self.corpus.append(gpa, bytes) catch @panic("OOM"); |
| 555 | | self.mutations.appendNTimes(gpa, m, 6) catch @panic("OOM"); |
| 556 | | |
| 557 | | // Write new corpus to cache |
| 558 | | var name_buf: [@sizeOf(usize) * 2]u8 = undefined; |
| 559 | | self.corpus_dir.writeFile(.{ |
| 560 | | .sub_path = std.fmt.bufPrint( |
| 561 | | &name_buf, |
| 562 | | "{x}", |
| 563 | | .{self.corpus_dir_idx}, |
| 564 | | ) catch unreachable, |
| 565 | | .data = bytes, |
| 566 | | }) catch |e| panic( |
| 567 | | "failed to write corpus file '{x}': {t}", |
| 568 | | .{ self.corpus_dir_idx, e }, |
| 569 | | ); |
| 570 | | self.corpus_dir_idx += 1; |
| 535 | const header = mem.bytesAsValue( |
| 536 | abi.SeenPcsHeader, |
| 537 | exec.shared_seen_pcs.items[0..@sizeOf(abi.SeenPcsHeader)], |
| 538 | ); |
| 539 | _ = @atomicRmw(usize, &header.unique_runs, .Add, 1, .monotonic); |
| 540 | |
| 541 | inst.setFresh(); |
| 542 | self.minimizeInput(); |
| 543 | inst.updateSeen(); |
| 544 | |
| 545 | // An empty-input has always been tried, so if an empty input is fresh then the |
| 546 | // test has to be non-deterministic. This has to be checked as duplicate empty |
| 547 | // entries are not allowed. |
| 548 | if (self.input.items.len - 8 == 0) { |
| 549 | std.log.warn("non-deterministic test (empty input produces different hits)", .{}); |
| 550 | _ = @atomicRmw(usize, &header.unique_runs, .Sub, 1, .monotonic); |
| 551 | return; |
| 571 | 552 | } |
| 572 | 553 | |
| 573 | | break; |
| 554 | const arena = self.arena_ctx.allocator(); |
| 555 | const bytes = arena.dupe(u8, @volatileCast(self.input.items[8..])) catch @panic("OOM"); |
| 556 | |
| 557 | self.corpus.append(gpa, bytes) catch @panic("OOM"); |
| 558 | self.mutations.appendNTimes(gpa, m, 6) catch @panic("OOM"); |
| 559 | |
| 560 | // Write new corpus to cache |
| 561 | var name_buf: [@sizeOf(usize) * 2]u8 = undefined; |
| 562 | self.corpus_dir.writeFile(.{ |
| 563 | .sub_path = std.fmt.bufPrint( |
| 564 | &name_buf, |
| 565 | "{x}", |
| 566 | .{self.corpus_dir_idx}, |
| 567 | ) catch unreachable, |
| 568 | .data = bytes, |
| 569 | }) catch |e| panic( |
| 570 | "failed to write corpus file '{x}': {t}", |
| 571 | .{ self.corpus_dir_idx, e }, |
| 572 | ); |
| 573 | self.corpus_dir_idx += 1; |
| 574 | 574 | } |
| 575 | 575 | } |
| 576 | 576 | }; |
| ... | ... | @@ -618,7 +618,7 @@ export fn fuzzer_new_input(bytes: abi.Slice) void { |
| 618 | 618 | export fn fuzzer_main(limit_kind: abi.LimitKind, amount: u64) void { |
| 619 | 619 | switch (limit_kind) { |
| 620 | 620 | .forever => while (true) fuzzer.cycle(), |
| 621 | | .iterations => for (0..amount -| 1) |_| fuzzer.cycle(), |
| 621 | .iterations => for (0..amount) |_| fuzzer.cycle(), |
| 622 | 622 | } |
| 623 | 623 | } |
| 624 | 624 | |