authorgravatar for squeek502@hotmail.comRyan Liptak <squeek502@hotmail.com> 2022-06-17 22:05:41-07:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-06-27 20:00:39+03:00
loga76775b50a65fd0ea0fd17d6ef3c42058df13997
tree46fea00ce7c12e66d898d02eff0c94b2d5ef0d4d
parent76f83282776151bd79715c4c00d13d06de633354

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

1 files changed, 4 insertions(+), 4 deletions(-)

lib/std/debug.zig+4-4
...@@ -180,11 +180,10 @@ pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void {...@@ -180,11 +180,10 @@ pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void {
180pub fn captureStackTrace(first_address: ?usize, stack_trace: *std.builtin.StackTrace) void {180pub fn captureStackTrace(first_address: ?usize, stack_trace: *std.builtin.StackTrace) void {
181 if (native_os == .windows) {181 if (native_os == .windows) {
182 const addrs = stack_trace.instruction_addresses;182 const addrs = stack_trace.instruction_addresses;
183 const u32_addrs_len = @intCast(u32, addrs.len);
184 const first_addr = first_address orelse {183 const first_addr = first_address orelse {
185 stack_trace.index = windows.ntdll.RtlCaptureStackBackTrace(184 stack_trace.index = windows.ntdll.RtlCaptureStackBackTrace(
186 0,185 0,
187 u32_addrs_len,186 @intCast(u32, addrs.len),
188 @ptrCast(**anyopaque, addrs.ptr),187 @ptrCast(**anyopaque, addrs.ptr),
189 null,188 null,
190 );189 );
...@@ -192,7 +191,7 @@ pub fn captureStackTrace(first_address: ?usize, stack_trace: *std.builtin.StackT...@@ -192,7 +191,7 @@ pub fn captureStackTrace(first_address: ?usize, stack_trace: *std.builtin.StackT
192 };191 };
193 var addr_buf_stack: [32]usize = undefined;192 var addr_buf_stack: [32]usize = undefined;
194 const addr_buf = if (addr_buf_stack.len > addrs.len) addr_buf_stack[0..] else addrs;193 const addr_buf = if (addr_buf_stack.len > addrs.len) addr_buf_stack[0..] else addrs;
195 const n = windows.ntdll.RtlCaptureStackBackTrace(0, u32_addrs_len, @ptrCast(**anyopaque, addr_buf.ptr), null);194 const n = windows.ntdll.RtlCaptureStackBackTrace(0, @intCast(u32, addr_buf.len), @ptrCast(**anyopaque, addr_buf.ptr), null);
196 const first_index = for (addr_buf[0..n]) |addr, i| {195 const first_index = for (addr_buf[0..n]) |addr, i| {
197 if (addr == first_addr) {196 if (addr == first_addr) {
198 break i;197 break i;
...@@ -201,7 +200,8 @@ pub fn captureStackTrace(first_address: ?usize, stack_trace: *std.builtin.StackT...@@ -201,7 +200,8 @@ pub fn captureStackTrace(first_address: ?usize, stack_trace: *std.builtin.StackT
201 stack_trace.index = 0;200 stack_trace.index = 0;
202 return;201 return;
203 };202 };
204 const slice = addr_buf[first_index..n];203 const end_index = math.min(first_index + addrs.len, n);
204 const slice = addr_buf[first_index..end_index];
205 // We use a for loop here because slice and addrs may alias.205 // We use a for loop here because slice and addrs may alias.
206 for (slice) |addr, i| {206 for (slice) |addr, i| {
207 addrs[i] = addr;207 addrs[i] = addr;