use RtlCaptureStackBackTrace on windows
parent
833477abf5
commit
f1b71053de
|
@ -578,6 +578,7 @@ set(ZIG_STD_FILES
|
|||
"os/windows/error.zig"
|
||||
"os/windows/index.zig"
|
||||
"os/windows/kernel32.zig"
|
||||
"os/windows/ntdll.zig"
|
||||
"os/windows/ole32.zig"
|
||||
"os/windows/shell32.zig"
|
||||
"os/windows/shlwapi.zig"
|
||||
|
|
|
@ -195,6 +195,10 @@ pub inline fn getReturnAddress(frame_count: usize) usize {
|
|||
}
|
||||
|
||||
pub fn writeCurrentStackTrace(out_stream: var, allocator: *mem.Allocator, debug_info: *DebugInfo, tty_color: bool, start_addr: ?usize) !void {
|
||||
switch (builtin.os) {
|
||||
builtin.Os.windows => return writeCurrentStackTraceWindows(out_stream, allocator, debug_info, tty_color, start_addr),
|
||||
else => {},
|
||||
}
|
||||
const AddressState = union(enum) {
|
||||
NotLookingForStartAddress,
|
||||
LookingForStartAddress: usize,
|
||||
|
@ -227,6 +231,24 @@ pub fn writeCurrentStackTrace(out_stream: var, allocator: *mem.Allocator, debug_
|
|||
}
|
||||
}
|
||||
|
||||
pub fn writeCurrentStackTraceWindows(out_stream: var, allocator: *mem.Allocator, debug_info: *DebugInfo,
|
||||
tty_color: bool, start_addr: ?usize) !void
|
||||
{
|
||||
var addr_buf: [1024]usize = undefined;
|
||||
const casted_len = @intCast(u32, addr_buf.len); // TODO shouldn't need this cast
|
||||
const n = windows.RtlCaptureStackBackTrace(0, casted_len, @ptrCast(**c_void, &addr_buf), null);
|
||||
const addrs = addr_buf[0..n];
|
||||
var start_i: usize = if (start_addr) |saddr| blk: {
|
||||
for (addrs) |addr, i| {
|
||||
if (addr == saddr) break :blk i;
|
||||
}
|
||||
return;
|
||||
} else 0;
|
||||
for (addrs[start_i..]) |addr| {
|
||||
try printSourceAtAddress(debug_info, out_stream, addr, tty_color);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn printSourceAtAddress(debug_info: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void {
|
||||
switch (builtin.os) {
|
||||
builtin.Os.macosx => return printSourceAtAddressMacOs(debug_info, out_stream, address, tty_color),
|
||||
|
@ -237,7 +259,7 @@ pub fn printSourceAtAddress(debug_info: *DebugInfo, out_stream: var, address: us
|
|||
}
|
||||
|
||||
fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void {
|
||||
const base_address = @ptrToInt(windows.GetModuleHandleW(null)); // returned HMODULE points to our executable file in memory
|
||||
const base_address = os.getBaseAddress();
|
||||
const relative_address = address - base_address;
|
||||
std.debug.warn("{x} - {x} => {x}\n", address, base_address, relative_address);
|
||||
try di.pdb.getSourceLine(relative_address);
|
||||
|
|
|
@ -271,6 +271,7 @@ pub const File = struct {
|
|||
const err = windows.GetLastError();
|
||||
return switch (err) {
|
||||
windows.ERROR.INVALID_PARAMETER => unreachable,
|
||||
windows.ERROR.INVALID_HANDLE => unreachable,
|
||||
else => os.unexpectedErrorWindows(err),
|
||||
};
|
||||
}
|
||||
|
|
|
@ -661,6 +661,7 @@ pub fn getBaseAddress() usize {
|
|||
return phdr - @sizeOf(ElfHeader);
|
||||
},
|
||||
builtin.Os.macosx => return @ptrToInt(&std.c._mh_execute_header),
|
||||
builtin.Os.windows => return @ptrToInt(windows.GetModuleHandleW(null)),
|
||||
else => @compileError("Unsupported OS"),
|
||||
}
|
||||
}
|
||||
|
@ -2069,7 +2070,7 @@ fn testWindowsCmdLine(input_cmd_line: [*]const u8, expected_args: []const []cons
|
|||
}
|
||||
|
||||
// TODO make this a build variable that you can set
|
||||
const unexpected_error_tracing = false;
|
||||
const unexpected_error_tracing = true;
|
||||
const UnexpectedError = error{
|
||||
/// The Operating System returned an undocumented error code.
|
||||
Unexpected,
|
||||
|
@ -2088,8 +2089,9 @@ pub fn unexpectedErrorPosix(errno: usize) UnexpectedError {
|
|||
/// Call this when you made a windows DLL call or something that does SetLastError
|
||||
/// and you get an unexpected error.
|
||||
pub fn unexpectedErrorWindows(err: windows.DWORD) UnexpectedError {
|
||||
if (true) {
|
||||
if (unexpected_error_tracing) {
|
||||
debug.warn("unexpected GetLastError(): {}\n", err);
|
||||
@breakpoint();
|
||||
debug.dumpCurrentStackTrace(null);
|
||||
}
|
||||
return error.Unexpected;
|
||||
|
|
|
@ -3,6 +3,7 @@ const assert = std.debug.assert;
|
|||
|
||||
pub use @import("advapi32.zig");
|
||||
pub use @import("kernel32.zig");
|
||||
pub use @import("ntdll.zig");
|
||||
pub use @import("ole32.zig");
|
||||
pub use @import("shell32.zig");
|
||||
pub use @import("shlwapi.zig");
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
use @import("index.zig");
|
||||
|
||||
pub extern "NtDll" stdcallcc fn RtlCaptureStackBackTrace(FramesToSkip: DWORD, FramesToCapture: DWORD, BackTrace: **c_void, BackTraceHash: ?*DWORD) WORD;
|
Loading…
Reference in New Issue