diff --git a/src/crash/minidump.zig b/src/crash/minidump.zig index 1e103283f..0abd67eae 100644 --- a/src/crash/minidump.zig +++ b/src/crash/minidump.zig @@ -1,5 +1,4 @@ -const reader = @import("minidump/reader.zig"); - +pub const reader = @import("minidump/reader.zig"); pub const stream = @import("minidump/stream.zig"); pub const Reader = reader.Reader; diff --git a/src/crash/minidump/external.zig b/src/crash/minidump/external.zig index a6f89d3e9..451810883 100644 --- a/src/crash/minidump/external.zig +++ b/src/crash/minidump/external.zig @@ -44,8 +44,7 @@ pub const MemoryDescriptor = extern struct { /// https://learn.microsoft.com/en-us/windows/win32/api/minidumpapiset/ns-minidumpapiset-minidump_thread_list pub const ThreadList = extern struct { number_of_threads: u32, - - // This struct has a trailing array of `Thread` structs. + threads: [1]Thread, }; /// https://learn.microsoft.com/en-us/windows/win32/api/minidumpapiset/ns-minidumpapiset-minidump_thread diff --git a/src/crash/minidump/reader.zig b/src/crash/minidump/reader.zig index 582044879..f316e63b0 100644 --- a/src/crash/minidump/reader.zig +++ b/src/crash/minidump/reader.zig @@ -13,6 +13,7 @@ const log = std.log.scoped(.minidump_reader); pub const ReadError = error{ InvalidHeader, InvalidVersion, + StreamSizeMismatch, }; /// Reader creates a new minidump reader for the given source type. The @@ -56,6 +57,9 @@ pub fn Reader(comptime S: type) type { /// The source type for the reader. pub const Source = S; + /// The stream types for reading + pub const ThreadList = stream.thread_list.ThreadListReader(Self); + /// The reader type for stream reading. This has some other methods so /// you must still call reader() on the result to get the actual /// reader to read the data. diff --git a/src/crash/minidump/stream.zig b/src/crash/minidump/stream.zig index bb383cce0..00ec6b042 100644 --- a/src/crash/minidump/stream.zig +++ b/src/crash/minidump/stream.zig @@ -1,10 +1,12 @@ const std = @import("std"); const assert = std.debug.assert; const Allocator = std.mem.Allocator; -const Reader = @import("reader.zig").Reader; const log = std.log.scoped(.minidump_stream); +/// The known stream types. +pub const thread_list = @import("stream_threadlist.zig"); + /// A stream within the minidump file. A stream can be either in an encoded /// form or decoded form. The encoded form are raw bytes and aren't validated /// until they're decoded. The decoded form is a structured form of the stream. @@ -23,55 +25,6 @@ pub const EncodedStream = struct { data: []const u8, }; -/// This is the list of threads from the process. -/// -/// ThreadList is stream type 0x3. -/// StreamReader is the Reader(T).StreamReader type. -pub fn ThreadList(comptime R: type) type { - return struct { - const Self = @This(); - - /// The number of threads in the list. - count: u32, - - /// The rva to the first thread in the list. - rva: u32, - - /// The source data and endianness so we can continue reading. - source: R.Source, - endian: std.builtin.Endian, - - pub fn init(r: *R.StreamReader) !Self { - assert(r.directory.stream_type == 0x3); - try r.seekToPayload(); - - const reader = r.source.reader(); - const count = try reader.readInt(u32, r.endian); - const rva = r.directory.location.rva + @as(u32, @intCast(@sizeOf(u32))); - - return .{ - .count = count, - .rva = rva, - .source = r.source, - .endian = r.endian, - }; - } - }; -} - -test "minidump: threadlist" { - const testing = std.testing; - - var fbs = std.io.fixedBufferStream(@embedFile("../testdata/macos.dmp")); - const R = Reader(*@TypeOf(fbs)); - const r = try R.init(&fbs); - - // Get our thread list stream - const dir = try r.directory(0); - try testing.expectEqual(3, dir.stream_type); - var sr = try r.streamReader(dir); - - // Get our rich structure - const v = try ThreadList(R).init(&sr); - log.warn("threadlist count={} rva={}", .{ v.count, v.rva }); +test { + @import("std").testing.refAllDecls(@This()); } diff --git a/src/crash/minidump/stream_threadlist.zig b/src/crash/minidump/stream_threadlist.zig new file mode 100644 index 000000000..e74d11e3e --- /dev/null +++ b/src/crash/minidump/stream_threadlist.zig @@ -0,0 +1,111 @@ +const std = @import("std"); +const assert = std.debug.assert; +const external = @import("external.zig"); +const readerpkg = @import("reader.zig"); +const Reader = readerpkg.Reader; +const ReadError = readerpkg.ReadError; + +const log = std.log.scoped(.minidump_stream); + +/// This is the list of threads from the process. +/// +/// This is the Reader implementation. You usually do not use this directly. +/// Instead, use Reader(T).ThreadList which will get you the same thing. +/// +/// ThreadList is stream type 0x3. +/// StreamReader is the Reader(T).StreamReader type. +pub fn ThreadListReader(comptime R: type) type { + return struct { + const Self = @This(); + + /// The number of threads in the list. + count: u32, + + /// The rva to the first thread in the list. + rva: u32, + + /// Source data and endianness so we can read. + source: R.Source, + endian: std.builtin.Endian, + + pub fn init(r: *R.StreamReader) !Self { + assert(r.directory.stream_type == 0x3); + try r.seekToPayload(); + const reader = r.source.reader(); + + // Our count is always a u32 in the header. + const count = try reader.readInt(u32, r.endian); + + // Determine if we have padding in our header. It is possible + // for there to be padding if the list header was written by + // a 32-bit process but is being read on a 64-bit process. + const padding = padding: { + const maybe_size = @sizeOf(u32) + (@sizeOf(external.Thread) * count); + switch (std.math.order(maybe_size, r.directory.location.data_size)) { + // It should never be larger than what the directory says. + .gt => return ReadError.StreamSizeMismatch, + + // If the sizes match exactly we're good. + .eq => break :padding 0, + + .lt => { + const padding = r.directory.location.data_size - maybe_size; + if (padding != 4) return ReadError.StreamSizeMismatch; + break :padding padding; + }, + } + }; + + // Rva is the location of the first thread in the list. + const rva = r.directory.location.rva + @as(u32, @sizeOf(u32)) + padding; + + return .{ + .count = count, + .rva = rva, + .source = r.source, + .endian = r.endian, + }; + } + + /// Get the thread entry for the given index. + /// + /// Index is asserted to be less than count. + pub fn thread(self: *const Self, i: usize) !external.Thread { + assert(i < self.count); + + // Seek to the thread + const offset: u32 = @intCast(@sizeOf(external.Thread) * i); + const rva: u32 = self.rva + offset; + try self.source.seekableStream().seekTo(rva); + + // Read the thread + return try self.source.reader().readStructEndian( + external.Thread, + self.endian, + ); + } + }; +} + +test "minidump: threadlist" { + const testing = std.testing; + + var fbs = std.io.fixedBufferStream(@embedFile("../testdata/macos.dmp")); + const R = Reader(*@TypeOf(fbs)); + const r = try R.init(&fbs); + + // Get our thread list stream + const dir = try r.directory(0); + try testing.expectEqual(3, dir.stream_type); + var sr = try r.streamReader(dir); + + // Get our rich structure + const v = try R.ThreadList.init(&sr); + log.warn("threadlist count={} rva={}", .{ v.count, v.rva }); + + try testing.expectEqual(12, v.count); + for (0..v.count) |i| { + const t = try v.thread(i); + log.warn("thread i={} thread={}", .{ i, t }); + } +} diff --git a/src/crash/testdata/macos.dmp b/src/crash/testdata/macos.dmp index 5931c13a06284043c286fcda9a94aa93f2762909..212cc7e624a1a670687dc20eca7f81e4db53ba5f 100644 GIT binary patch delta 31642 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 I<%%)^04%~OGXMYp delta 31643 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 Ip^#lG00EKxM*si-