code coverage dumping tool basic implementation

* std.debug.Dwarf: add `sortCompileUnits` along with a field to track
  the state for the purpose of assertions and correct API usage.
  This makes batch lookups faster.
  - in the future, findCompileUnit should be enhanced to rely on sorted
    compile units as well.
* implement `std.debug.Dwarf.resolveSourceLocations` as well as
  `std.debug.Info.resolveSourceLocations`. It's still pretty slow, since
  it calls getLineNumberInfo for each array element, repeating a lot of
  work unnecessarily.
* integrate these APIs with `std.Progress` to understand what is taking
  so long.

The output I'm seeing from this tool shows a lot of missing source
locations. In particular, the main area of interest is missing for my
tokenizer fuzzing example.
This commit is contained in:
Andrew Kelley
2024-08-02 17:45:31 -07:00
parent 2e12b45d8b
commit de47acd732
4 changed files with 102 additions and 16 deletions

View File

@@ -20,9 +20,14 @@ address_map: std.AutoArrayHashMapUnmanaged(u64, Dwarf.ElfModule),
pub const LoadError = Dwarf.ElfModule.LoadError;
pub fn load(gpa: Allocator, path: Path) LoadError!Info {
pub fn load(gpa: Allocator, path: Path, parent_prog_node: std.Progress.Node) LoadError!Info {
var sections: Dwarf.SectionArray = Dwarf.null_section_array;
const elf_module = try Dwarf.ElfModule.loadPath(gpa, path, null, null, &sections, null);
var prog_node = parent_prog_node.start("Loading Debug Info", 0);
defer prog_node.end();
var elf_module = try Dwarf.ElfModule.loadPath(gpa, path, null, null, &sections, null);
prog_node.end();
prog_node = parent_prog_node.start("Sort Compile Units", 0);
try elf_module.dwarf.sortCompileUnits();
var info: Info = .{
.address_map = .{},
};
@@ -38,10 +43,7 @@ pub fn deinit(info: *Info, gpa: Allocator) void {
info.* = undefined;
}
pub const ResolveSourceLocationsError = error{
MissingDebugInfo,
InvalidDebugInfo,
} || Allocator.Error;
pub const ResolveSourceLocationsError = Dwarf.ResolveSourceLocationsError;
pub fn resolveSourceLocations(
info: *Info,
@@ -49,9 +51,10 @@ pub fn resolveSourceLocations(
sorted_pc_addrs: []const u64,
/// Asserts its length equals length of `sorted_pc_addrs`.
output: []std.debug.SourceLocation,
parent_prog_node: std.Progress.Node,
) ResolveSourceLocationsError!void {
assert(sorted_pc_addrs.len == output.len);
if (info.address_map.entries.len != 1) @panic("TODO");
const elf_module = &info.address_map.values()[0];
return elf_module.dwarf.resolveSourceLocations(gpa, sorted_pc_addrs, output);
return elf_module.dwarf.resolveSourceLocations(gpa, sorted_pc_addrs, output, parent_prog_node);
}