From a76775b50a65fd0ea0fd17d6ef3c42058df13997 Mon Sep 17 00:00:00 2001 From: Ryan Liptak Date: Fri, 17 Jun 2022 22:05:41 -0700 Subject: [PATCH] Fix stack traces with non-null `first_address` on Windows Before this commit, the passed in length would always be given to the RtlCaptureStackBackTrace call. Now we always give the length of the actual buffer we're using (the addr_buf_stack size of 32 or the passed in length if it's larger than 32; this matches what the doc comment says the function was meant to be doing as well). This was causing empty stack traces for things like the GeneralPurposeAllocator leak checking. Fixes #6687 --- lib/std/debug.zig | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/std/debug.zig b/lib/std/debug.zig index af5d54ae62..54c614f270 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -180,11 +180,10 @@ pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void { pub fn captureStackTrace(first_address: ?usize, stack_trace: *std.builtin.StackTrace) void { if (native_os == .windows) { const addrs = stack_trace.instruction_addresses; - const u32_addrs_len = @intCast(u32, addrs.len); const first_addr = first_address orelse { stack_trace.index = windows.ntdll.RtlCaptureStackBackTrace( 0, - u32_addrs_len, + @intCast(u32, addrs.len), @ptrCast(**anyopaque, addrs.ptr), null, ); @@ -192,7 +191,7 @@ pub fn captureStackTrace(first_address: ?usize, stack_trace: *std.builtin.StackT }; var addr_buf_stack: [32]usize = undefined; const addr_buf = if (addr_buf_stack.len > addrs.len) addr_buf_stack[0..] else addrs; - const n = windows.ntdll.RtlCaptureStackBackTrace(0, u32_addrs_len, @ptrCast(**anyopaque, addr_buf.ptr), null); + const n = windows.ntdll.RtlCaptureStackBackTrace(0, @intCast(u32, addr_buf.len), @ptrCast(**anyopaque, addr_buf.ptr), null); const first_index = for (addr_buf[0..n]) |addr, i| { if (addr == first_addr) { break i; @@ -201,7 +200,8 @@ pub fn captureStackTrace(first_address: ?usize, stack_trace: *std.builtin.StackT stack_trace.index = 0; return; }; - const slice = addr_buf[first_index..n]; + const end_index = math.min(first_index + addrs.len, n); + const slice = addr_buf[first_index..end_index]; // We use a for loop here because slice and addrs may alias. for (slice) |addr, i| { addrs[i] = addr;