Commit cbdf9bf5ee

Xavier Bouchoux <xavierb@gmail.com>
2024-08-07 08:57:25
std.debug.Dwarf: try to load the debuginfo from the debuginfod cache.
The previous mecanism for linux distributions to delivers debug info into `/usr/lib/debug` no longer seems in use. the current mecanism often is using `debuginfod` (https://sourceware.org/elfutils/Debuginfod.html) This commit only tries to load already available debuginfo but does not try to make any download requests. the user can manually run `debuginfod-find debuginfo PATH` to populate the cache.
1 parent 7e966de
Changed files (1)
lib
std
debug
lib/std/debug/Dwarf.zig
@@ -2215,6 +2215,46 @@ pub const ElfModule = struct {
                 return error.MissingDebugInfo;
             }
 
+            // $XDG_CACHE_HOME/debuginfod_client/<buildid>/debuginfo
+            // This only opportunisticly tries to load from the debuginfod cache, but doesn't try to populate it.
+            // One can manually run `debuginfod-find debuginfo PATH` to download the symbols
+            if (build_id) |id| blk: {
+                var debuginfod_dir: std.fs.Dir = switch (builtin.os.tag) {
+                    .wasi, .windows => break :blk,
+                    else => dir: {
+                        if (std.posix.getenv("DEBUGINFOD_CACHE_PATH")) |path| {
+                            break :dir std.fs.openDirAbsolute(path, .{}) catch break :blk;
+                        }
+                        if (std.posix.getenv("XDG_CACHE_HOME")) |cache_path| {
+                            const path = std.fs.path.join(gpa, &[_][]const u8{ cache_path, "debuginfod_client" }) catch break :blk;
+                            defer gpa.free(path);
+                            break :dir std.fs.openDirAbsolute(path, .{}) catch break :blk;
+                        }
+                        if (std.posix.getenv("HOME")) |home_path| {
+                            const path = std.fs.path.join(gpa, &[_][]const u8{ home_path, ".cache", "debuginfod_client" }) catch break :blk;
+                            defer gpa.free(path);
+                            break :dir std.fs.openDirAbsolute(path, .{}) catch break :blk;
+                        }
+                        break :blk;
+                    },
+                };
+                defer debuginfod_dir.close();
+
+                const filename = std.fmt.allocPrint(
+                    gpa,
+                    "{s}/debuginfo",
+                    .{std.fmt.fmtSliceHexLower(id)},
+                ) catch break :blk;
+                defer gpa.free(filename);
+
+                const path: Path = .{
+                    .root_dir = .{ .path = null, .handle = debuginfod_dir },
+                    .sub_path = filename,
+                };
+
+                return loadPath(gpa, path, null, separate_debug_crc, &sections, mapped_mem) catch break :blk;
+            }
+
             const global_debug_directories = [_][]const u8{
                 "/usr/lib/debug",
             };