From 9178d1cf38f94d132bc6c99321e7a13df3eb5e94 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sun, 8 Sep 2024 21:25:34 -0700 Subject: [PATCH] crash/minidump: locationReader to read locations in a minidump --- src/crash/minidump/reader.zig | 17 ++++++++++++++++- src/crash/minidump/stream_threadlist.zig | 6 ++++++ 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/crash/minidump/reader.zig b/src/crash/minidump/reader.zig index f316e63b0..f792d6670 100644 --- a/src/crash/minidump/reader.zig +++ b/src/crash/minidump/reader.zig @@ -54,6 +54,9 @@ pub fn Reader(comptime S: type) type { const SourceReader = @typeInfo(@TypeOf(SourceCallable.reader)).Fn.return_type.?; const SourceSeeker = @typeInfo(@TypeOf(SourceCallable.seekableStream)).Fn.return_type.?; + /// A limited reader for reading data from the source. + pub const LimitedReader = std.io.LimitedReader(SourceReader); + /// The source type for the reader. pub const Source = S; @@ -72,7 +75,6 @@ pub fn Reader(comptime S: type) type { /// reader() is called. limit_reader: LimitedReader = undefined, - const LimitedReader = std.io.LimitedReader(SourceReader); pub const Reader = LimitedReader.Reader; /// Returns a Reader implementation that reads the bytes of the @@ -164,6 +166,19 @@ pub fn Reader(comptime S: type) type { self.endian, ); } + + /// Return a reader for the given location descriptor. This is only + /// valid until the reader source is modified in some way. + pub fn locationReader( + self: *const Self, + loc: external.LocationDescriptor, + ) !LimitedReader { + try self.source.seekableStream().seekTo(loc.rva); + return .{ + .inner_reader = self.source.reader(), + .bytes_left = loc.data_size, + }; + } }; } diff --git a/src/crash/minidump/stream_threadlist.zig b/src/crash/minidump/stream_threadlist.zig index e74d11e3e..51f3f9d4c 100644 --- a/src/crash/minidump/stream_threadlist.zig +++ b/src/crash/minidump/stream_threadlist.zig @@ -89,6 +89,7 @@ pub fn ThreadListReader(comptime R: type) type { test "minidump: threadlist" { const testing = std.testing; + const alloc = testing.allocator; var fbs = std.io.fixedBufferStream(@embedFile("../testdata/macos.dmp")); const R = Reader(*@TypeOf(fbs)); @@ -107,5 +108,10 @@ test "minidump: threadlist" { for (0..v.count) |i| { const t = try v.thread(i); log.warn("thread i={} thread={}", .{ i, t }); + + // Read our stack memory + var stack_reader = try r.locationReader(t.stack.memory); + const bytes = try stack_reader.reader().readAllAlloc(alloc, t.stack.memory.data_size); + defer alloc.free(bytes); } }