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
This commit is contained in:
Ryan Liptak 2022-06-17 22:05:41 -07:00 committed by Veikka Tuominen
parent 76f8328277
commit a76775b50a

View File

@ -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;