╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ dump-cov.zig ─────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭ find file ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╮ ╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │ │ │http│ ssh │ │ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─╯ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
25 }; 26 27 const target = std.zig.resolveTargetQueryOrFatal(io, try .parse(.{ 28 .arch_os_abi = target_query_str, 29 })); 30 31 const exe_file_name = args[1]; 32 const cov_file_name = args[2]; 33 34 const exe_path: Path = .{ 35 .root_dir = .cwd(), 36 .sub_path = exe_file_name, 37 }; 38 const cov_path: Path = .{ 39 .root_dir = .cwd(), 40 .sub_path = cov_file_name, 41 }; 42 43 var coverage: std.debug.Coverage = .init; 44 defer coverage.deinit(gpa); 45 46 var debug_info = std.debug.Info.load(gpa, io, exe_path, &coverage, target.ofmt, target.cpu.arch) catch |err| { 47 fatal("failed to load debug info for {f}: {t}", .{ exe_path, err }); 48 }; 49 defer debug_info.deinit(gpa); 50 51 const cov_bytes = cov_path.root_dir.handle.readFileAllocOptions( 52 io, 53 cov_path.sub_path, 54 arena, 55 .limited(1 << 30), 56 .of(SeenPcsHeader), 57 null, 58 ) catch |err| { 59 fatal("failed to load coverage file {f}: {s}", .{ cov_path, @errorName(err) }); 60 }; 61 62 var stdout_buffer: [4000]u8 = undefined; 63 var stdout_writer = Io.File.stdout().writerStreaming(io, &stdout_buffer); 64 const stdout = &stdout_writer.interface; 65 66 const header: *SeenPcsHeader = @ptrCast(cov_bytes); 67 try stdout.print("{any}\n", .{header.*}); 68 const pcs = header.pcAddrs(); 69 70 var indexed_pcs: std.array_hash_map.Auto(usize, void) = .empty; 71 try indexed_pcs.entries.resize(arena, pcs.len); 72 @memcpy(indexed_pcs.entries.items(.key), pcs); 73 try indexed_pcs.reIndex(arena); 74 75 const sorted_pcs = try arena.dupe(usize, pcs); 76 std.mem.sortUnstable(usize, sorted_pcs, {}, std.sort.asc(usize)); 77 78 const source_locations = try arena.alloc(std.debug.Coverage.SourceLocation, sorted_pcs.len); 79 try debug_info.resolveAddresses(gpa, io, sorted_pcs, source_locations); 80 81 const seen_pcs = header.seenBits(); 82 83 for (sorted_pcs, source_locations) |pc, sl| { 84 if (sl.file == .invalid) { 85 try stdout.print(" {x}: invalid\n", .{pc}); 86 continue; 87 } 88 const file = debug_info.coverage.fileAt(sl.file); 89 const dir_name = debug_info.coverage.directories.keys()[file.directory_index]; 90 const dir_name_slice = debug_info.coverage.stringAt(dir_name); 91 const seen_i = indexed_pcs.getIndex(pc).?; 92 const hit: u1 = @truncate(seen_pcs[seen_i / @bitSizeOf(usize)] >> @intCast(seen_i % @bitSizeOf(usize))); 93 try stdout.print("{c}{x}: {s}/{s}:{d}:{d}\n", .{ 94 "-+"[hit], pc, dir_name_slice, debug_info.coverage.stringAt(file.basename), sl.line, sl.column, 95 }); 96 } 97 98 try stdout.flush(); 99 } 100