aboutsummaryrefslogtreecommitdiff
path: root/lib/std/debug/SelfInfo/WindowsModule.zig
diff options
context:
space:
mode:
authormlugg <mlugg@mlugg.co.uk>2025-09-03 15:42:33 +0100
committermlugg <mlugg@mlugg.co.uk>2025-09-30 13:44:50 +0100
commitc895aa7a35b178576b89e600a20af9d16da36dea (patch)
tree0816ce721cd4343b5abd3c86187ca064b8826420 /lib/std/debug/SelfInfo/WindowsModule.zig
parentdd9cb1beead2d0b9a22decf089aadf51cfe90da8 (diff)
downloadzig-c895aa7a35b178576b89e600a20af9d16da36dea.tar.gz
zig-c895aa7a35b178576b89e600a20af9d16da36dea.zip
std.debug.SelfInfo: concrete error sets
The downside of this commit is that more precise errors are no longer propagated up. However, these errors were pretty useless in isolation due to them having no context; and regardless, we intentionally swallow most of them in `std.debug` anyway. Therefore, this is better in practice, because it allows `std.debug` to give slightly more useful warnings when handling errors. This commit does that for unwind errors, for instance, which differentiate between the unwind info being corrupt vs missing vs inaccessible vs unsupported. A better solution would be to also include more detailed information via the diagnostics pattern, but this commit is an incremental improvement.
Diffstat (limited to 'lib/std/debug/SelfInfo/WindowsModule.zig')
-rw-r--r--lib/std/debug/SelfInfo/WindowsModule.zig19
1 files changed, 12 insertions, 7 deletions
diff --git a/lib/std/debug/SelfInfo/WindowsModule.zig b/lib/std/debug/SelfInfo/WindowsModule.zig
index 4f9d98353b..674c6adae5 100644
--- a/lib/std/debug/SelfInfo/WindowsModule.zig
+++ b/lib/std/debug/SelfInfo/WindowsModule.zig
@@ -5,7 +5,7 @@ handle: windows.HMODULE,
pub fn key(m: WindowsModule) usize {
return m.base_address;
}
-pub fn lookup(cache: *LookupCache, gpa: Allocator, address: usize) !WindowsModule {
+pub fn lookup(cache: *LookupCache, gpa: Allocator, address: usize) std.debug.SelfInfo.Error!WindowsModule {
if (lookupInCache(cache, address)) |m| return m;
{
// Check a new module hasn't been loaded
@@ -29,18 +29,23 @@ pub fn lookup(cache: *LookupCache, gpa: Allocator, address: usize) !WindowsModul
if (lookupInCache(cache, address)) |m| return m;
return error.MissingDebugInfo;
}
-pub fn getSymbolAtAddress(module: *const WindowsModule, gpa: Allocator, di: *DebugInfo, address: usize) !std.debug.Symbol {
- if (!di.loaded) try module.loadLocationInfo(gpa, di);
+pub fn getSymbolAtAddress(module: *const WindowsModule, gpa: Allocator, di: *DebugInfo, address: usize) std.debug.SelfInfo.Error!std.debug.Symbol {
+ if (!di.loaded) module.loadDebugInfo(gpa, di) catch |err| switch (err) {
+ error.OutOfMemory, error.InvalidDebugInfo, error.MissingDebugInfo, error.Unexpected => |e| return e,
+ error.FileNotFound => return error.MissingDebugInfo,
+ error.UnknownPDBVersion => return error.UnsupportedDebugInfo,
+ else => return error.ReadFailed,
+ };
// Translate the runtime address into a virtual address into the module
const vaddr = address - module.base_address;
if (di.pdb != null) {
- if (try di.getSymbolFromPdb(vaddr)) |symbol| return symbol;
+ if (di.getSymbolFromPdb(vaddr) catch return error.InvalidDebugInfo) |symbol| return symbol;
}
if (di.dwarf) |*dwarf| {
const dwarf_address = vaddr + di.coff_image_base;
- return dwarf.getSymbol(gpa, native_endian, dwarf_address);
+ return dwarf.getSymbol(gpa, native_endian, dwarf_address) catch return error.InvalidDebugInfo;
}
return error.MissingDebugInfo;
@@ -59,7 +64,7 @@ fn lookupInCache(cache: *const LookupCache, address: usize) ?WindowsModule {
}
return null;
}
-fn loadLocationInfo(module: *const WindowsModule, gpa: Allocator, di: *DebugInfo) !void {
+fn loadDebugInfo(module: *const WindowsModule, gpa: Allocator, di: *DebugInfo) !void {
const mapped_ptr: [*]const u8 = @ptrFromInt(module.base_address);
const mapped = mapped_ptr[0..module.size];
var coff_obj = coff.Coff.init(mapped, true) catch return error.InvalidDebugInfo;
@@ -151,7 +156,7 @@ fn loadLocationInfo(module: *const WindowsModule, gpa: Allocator, di: *DebugInfo
di.pdb = Pdb.init(gpa, path) catch |err| switch (err) {
error.FileNotFound, error.IsDir => break :pdb,
- else => return err,
+ else => |e| return e,
};
try di.pdb.?.parseInfoStream();
try di.pdb.?.parseDbiStream();