diff options
| author | Andrew Kelley <andrew@ziglang.org> | 2020-01-30 09:26:39 -0500 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-01-30 09:26:39 -0500 |
| commit | 0303e7bd8e4fb245b4dfae51c7c1e34a66e0855c (patch) | |
| tree | 28721c76baf99b6c07bafe3a797073a43a112f2a /lib/std/debug.zig | |
| parent | e77a102e24c351a56cdda5bad5a46dcd58101c23 (diff) | |
| parent | a5f18c2b2ae86126e0fd0cba67676ae68ba0f1df (diff) | |
| download | zig-0303e7bd8e4fb245b4dfae51c7c1e34a66e0855c.tar.gz zig-0303e7bd8e4fb245b4dfae51c7c1e34a66e0855c.zip | |
Merge pull request #4319 from Rocknest/windows-traces
Bring windows segfault handler on par with linux
Diffstat (limited to 'lib/std/debug.zig')
| -rw-r--r-- | lib/std/debug.zig | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/lib/std/debug.zig b/lib/std/debug.zig index a5fd1a4712..28340fede2 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -131,6 +131,7 @@ pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void { const tty_config = detectTTYConfig(); printSourceAtAddress(debug_info, stderr, ip, tty_config) catch return; const first_return_address = @intToPtr(*const usize, bp + @sizeOf(usize)).*; + if (first_return_address == 0) return; // The whole call stack may be optimized out printSourceAtAddress(debug_info, stderr, first_return_address - 1, tty_config) catch return; var it = StackIterator{ .first_addr = null, @@ -325,6 +326,7 @@ pub const StackIterator = struct { } const return_address = @intToPtr(*const usize, self.fp - fp_adjust_factor + @sizeOf(usize)).*; + if (return_address == 0) return null; return return_address; } }; @@ -470,7 +472,7 @@ fn printSourceAtAddressWindows( line_index += @sizeOf(pdb.LineNumberEntry); const vaddr_start = frag_vaddr_start + line_num_entry.Offset; - if (relative_address <= vaddr_start) { + if (relative_address < vaddr_start) { break; } } @@ -2309,16 +2311,39 @@ fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: *const c_vo } fn handleSegfaultWindows(info: *windows.EXCEPTION_POINTERS) callconv(.Stdcall) c_long { - const exception_address = @ptrToInt(info.ExceptionRecord.ExceptionAddress); switch (info.ExceptionRecord.ExceptionCode) { - windows.EXCEPTION_DATATYPE_MISALIGNMENT => panicExtra(null, exception_address, "Unaligned Memory Access", .{}), - windows.EXCEPTION_ACCESS_VIOLATION => panicExtra(null, exception_address, "Segmentation fault at address 0x{x}", .{info.ExceptionRecord.ExceptionInformation[1]}), - windows.EXCEPTION_ILLEGAL_INSTRUCTION => panicExtra(null, exception_address, "Illegal Instruction", .{}), - windows.EXCEPTION_STACK_OVERFLOW => panicExtra(null, exception_address, "Stack Overflow", .{}), + windows.EXCEPTION_DATATYPE_MISALIGNMENT => handleSegfaultWindowsExtra(info, 0, "Unaligned Memory Access"), + windows.EXCEPTION_ACCESS_VIOLATION => handleSegfaultWindowsExtra(info, 1, null), + windows.EXCEPTION_ILLEGAL_INSTRUCTION => handleSegfaultWindowsExtra(info, 2, null), + windows.EXCEPTION_STACK_OVERFLOW => handleSegfaultWindowsExtra(info, 0, "Stack Overflow"), else => return windows.EXCEPTION_CONTINUE_SEARCH, } } +// zig won't let me use an anon enum here https://github.com/ziglang/zig/issues/3707 +fn handleSegfaultWindowsExtra(info: *windows.EXCEPTION_POINTERS, comptime msg: u8, comptime format: ?[]const u8) noreturn { + const exception_address = @ptrToInt(info.ExceptionRecord.ExceptionAddress); + if (@hasDecl(windows, "CONTEXT")) { + const regs = info.ContextRecord.getRegs(); + switch (msg) { + 0 => std.debug.warn("{}\n", .{format.?}), + 1 => std.debug.warn("Segmentation fault at address 0x{x}\n", .{info.ExceptionRecord.ExceptionInformation[1]}), + 2 => std.debug.warn("Illegal instruction at address 0x{x}\n", .{regs.ip}), + else => unreachable, + } + + dumpStackTraceFromBase(regs.bp, regs.ip); + os.abort(); + } else { + switch (msg) { + 0 => panicExtra(null, exception_address, format.?, .{}), + 1 => panicExtra(null, exception_address, "Segmentation fault at address 0x{x}", .{info.ExceptionRecord.ExceptionInformation[1]}), + 2 => panicExtra(null, exception_address, "Illegal Instruction", .{}), + else => unreachable, + } + } +} + pub fn dumpStackPointerAddr(prefix: []const u8) void { const sp = asm ("" : [argc] "={rsp}" (-> usize) |
