authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-08-29 16:35:51-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-08-29 16:35:51-04:00
logf1b71053de6c5e71e2e1f73daeaff29280b69350
tree6e27b78ebc073622dec68d49f809fe5ceb5fe674
parent833477abf5a7df2c8861a2df11fae2105016e087

use RtlCaptureStackBackTrace on windows


6 files changed, 33 insertions(+), 3 deletions(-)

CMakeLists.txt+1
......@@ -578,6 +578,7 @@ set(ZIG_STD_FILES
578578 "os/windows/error.zig"
579579 "os/windows/index.zig"
580580 "os/windows/kernel32.zig"
581 "os/windows/ntdll.zig"
581582 "os/windows/ole32.zig"
582583 "os/windows/shell32.zig"
583584 "os/windows/shlwapi.zig"
std/debug/index.zig+23-1
......@@ -195,6 +195,10 @@ pub inline fn getReturnAddress(frame_count: usize) usize {
195195}
196196
197197pub fn writeCurrentStackTrace(out_stream: var, allocator: *mem.Allocator, debug_info: *DebugInfo, tty_color: bool, start_addr: ?usize) !void {
198 switch (builtin.os) {
199 builtin.Os.windows => return writeCurrentStackTraceWindows(out_stream, allocator, debug_info, tty_color, start_addr),
200 else => {},
201 }
198202 const AddressState = union(enum) {
199203 NotLookingForStartAddress,
200204 LookingForStartAddress: usize,
......@@ -227,6 +231,24 @@ pub fn writeCurrentStackTrace(out_stream: var, allocator: *mem.Allocator, debug_
227231 }
228232}
229233
234pub fn writeCurrentStackTraceWindows(out_stream: var, allocator: *mem.Allocator, debug_info: *DebugInfo,
235 tty_color: bool, start_addr: ?usize) !void
236{
237 var addr_buf: [1024]usize = undefined;
238 const casted_len = @intCast(u32, addr_buf.len); // TODO shouldn't need this cast
239 const n = windows.RtlCaptureStackBackTrace(0, casted_len, @ptrCast(**c_void, &addr_buf), null);
240 const addrs = addr_buf[0..n];
241 var start_i: usize = if (start_addr) |saddr| blk: {
242 for (addrs) |addr, i| {
243 if (addr == saddr) break :blk i;
244 }
245 return;
246 } else 0;
247 for (addrs[start_i..]) |addr| {
248 try printSourceAtAddress(debug_info, out_stream, addr, tty_color);
249 }
250}
251
230252pub fn printSourceAtAddress(debug_info: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void {
231253 switch (builtin.os) {
232254 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
237259}
238260
239261fn printSourceAtAddressWindows(di: *DebugInfo, out_stream: var, address: usize, tty_color: bool) !void {
240 const base_address = @ptrToInt(windows.GetModuleHandleW(null)); // returned HMODULE points to our executable file in memory
262 const base_address = os.getBaseAddress();
241263 const relative_address = address - base_address;
242264 std.debug.warn("{x} - {x} => {x}\n", address, base_address, relative_address);
243265 try di.pdb.getSourceLine(relative_address);
std/os/file.zig+1
......@@ -271,6 +271,7 @@ pub const File = struct {
271271 const err = windows.GetLastError();
272272 return switch (err) {
273273 windows.ERROR.INVALID_PARAMETER => unreachable,
274 windows.ERROR.INVALID_HANDLE => unreachable,
274275 else => os.unexpectedErrorWindows(err),
275276 };
276277 }
std/os/index.zig+4-2
......@@ -661,6 +661,7 @@ pub fn getBaseAddress() usize {
661661 return phdr - @sizeOf(ElfHeader);
662662 },
663663 builtin.Os.macosx => return @ptrToInt(&std.c._mh_execute_header),
664 builtin.Os.windows => return @ptrToInt(windows.GetModuleHandleW(null)),
664665 else => @compileError("Unsupported OS"),
665666 }
666667}
......@@ -2069,7 +2070,7 @@ fn testWindowsCmdLine(input_cmd_line: [*]const u8, expected_args: []const []cons
20692070}
20702071
20712072// TODO make this a build variable that you can set
2072const unexpected_error_tracing = false;
2073const unexpected_error_tracing = true;
20732074const UnexpectedError = error{
20742075 /// The Operating System returned an undocumented error code.
20752076 Unexpected,
......@@ -2088,8 +2089,9 @@ pub fn unexpectedErrorPosix(errno: usize) UnexpectedError {
20882089/// Call this when you made a windows DLL call or something that does SetLastError
20892090/// and you get an unexpected error.
20902091pub fn unexpectedErrorWindows(err: windows.DWORD) UnexpectedError {
2091 if (true) {
2092 if (unexpected_error_tracing) {
20922093 debug.warn("unexpected GetLastError(): {}\n", err);
2094 @breakpoint();
20932095 debug.dumpCurrentStackTrace(null);
20942096 }
20952097 return error.Unexpected;
std/os/windows/index.zig+1
......@@ -3,6 +3,7 @@ const assert = std.debug.assert;
33
44pub use @import("advapi32.zig");
55pub use @import("kernel32.zig");
6pub use @import("ntdll.zig");
67pub use @import("ole32.zig");
78pub use @import("shell32.zig");
89pub use @import("shlwapi.zig");
std/os/windows/ntdll.zig created+3
......@@ -0,0 +1,3 @@
1use @import("index.zig");
2
3pub extern "NtDll" stdcallcc fn RtlCaptureStackBackTrace(FramesToSkip: DWORD, FramesToCapture: DWORD, BackTrace: **c_void, BackTraceHash: ?*DWORD) WORD;