Commit f1b71053de
std/debug/index.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);
std/os/windows/index.zig
@@ -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");
std/os/windows/ntdll.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;
std/os/file.zig
@@ -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),
};
}
std/os/index.zig
@@ -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;
CMakeLists.txt
@@ -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"