mirror of
https://github.com/ziglang/zig.git
synced 2025-12-06 06:13:07 +00:00
with debug info resolved. begin efforts of providing `std.debug.Info`, a cross-platform abstraction for loading debug information into an in-memory format that supports queries such as "what is the source location of this virtual memory address?" Unlike `std.debug.SelfInfo`, this API does not assume the debug information in question happens to match the host CPU architecture, OS, or other target properties.
71 lines
2.5 KiB
Zig
71 lines
2.5 KiB
Zig
//! Reads a Zig coverage file and prints human-readable information to stdout,
|
|
//! including file:line:column information for each PC.
|
|
|
|
const std = @import("std");
|
|
const fatal = std.process.fatal;
|
|
const Path = std.Build.Cache.Path;
|
|
const assert = std.debug.assert;
|
|
|
|
pub fn main() !void {
|
|
var general_purpose_allocator: std.heap.GeneralPurposeAllocator(.{}) = .{};
|
|
defer _ = general_purpose_allocator.deinit();
|
|
const gpa = general_purpose_allocator.allocator();
|
|
|
|
var arena_instance = std.heap.ArenaAllocator.init(gpa);
|
|
defer arena_instance.deinit();
|
|
const arena = arena_instance.allocator();
|
|
|
|
const args = try std.process.argsAlloc(arena);
|
|
const exe_file_name = args[1];
|
|
const cov_file_name = args[2];
|
|
|
|
const exe_path: Path = .{
|
|
.root_dir = std.Build.Cache.Directory.cwd(),
|
|
.sub_path = exe_file_name,
|
|
};
|
|
const cov_path: Path = .{
|
|
.root_dir = std.Build.Cache.Directory.cwd(),
|
|
.sub_path = cov_file_name,
|
|
};
|
|
|
|
var debug_info = std.debug.Info.load(gpa, exe_path) catch |err| {
|
|
fatal("failed to load debug info for {}: {s}", .{ exe_path, @errorName(err) });
|
|
};
|
|
defer debug_info.deinit(gpa);
|
|
|
|
const cov_bytes = cov_path.root_dir.handle.readFileAlloc(arena, cov_path.sub_path, 1 << 30) catch |err| {
|
|
fatal("failed to load coverage file {}: {s}", .{ cov_path, @errorName(err) });
|
|
};
|
|
|
|
var bw = std.io.bufferedWriter(std.io.getStdOut().writer());
|
|
const stdout = bw.writer();
|
|
|
|
const header: *align(1) SeenPcsHeader = @ptrCast(cov_bytes);
|
|
try stdout.print("{any}\n", .{header.*});
|
|
//const n_bitset_elems = (header.pcs_len + 7) / 8;
|
|
const pcs_bytes = cov_bytes[@sizeOf(SeenPcsHeader)..][0 .. header.pcs_len * @sizeOf(usize)];
|
|
const pcs = try arena.alloc(usize, header.pcs_len);
|
|
for (0..pcs_bytes.len / @sizeOf(usize), pcs) |i, *pc| {
|
|
pc.* = std.mem.readInt(usize, pcs_bytes[i * @sizeOf(usize) ..][0..@sizeOf(usize)], .little);
|
|
}
|
|
assert(std.sort.isSorted(usize, pcs, {}, std.sort.asc(usize)));
|
|
|
|
const source_locations = try arena.alloc(std.debug.SourceLocation, pcs.len);
|
|
try debug_info.resolveSourceLocations(gpa, pcs, source_locations);
|
|
|
|
for (pcs, source_locations) |pc, sl| {
|
|
try stdout.print("{x}: {s}:{d}:{d}\n", .{
|
|
pc, sl.file_name, sl.line, sl.column,
|
|
});
|
|
}
|
|
|
|
try bw.flush();
|
|
}
|
|
|
|
const SeenPcsHeader = extern struct {
|
|
n_runs: usize,
|
|
deduplicated_runs: usize,
|
|
pcs_len: usize,
|
|
lowest_stack: usize,
|
|
};
|