From 3500b41bfed159b54b951b7cee5ff404ae5fbbda Mon Sep 17 00:00:00 2001 From: Rocknest <35231115+Rocknest@users.noreply.github.com> Date: Wed, 29 Jan 2020 16:57:43 +0200 Subject: Add an advanced segfault handler on windows --- lib/std/debug.zig | 278 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 273 insertions(+), 5 deletions(-) (limited to 'lib/std/debug.zig') diff --git a/lib/std/debug.zig b/lib/std/debug.zig index d035707a54..561993fb99 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -2307,16 +2307,284 @@ 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 +fn handleSegfaultWindowsExtra(info: *windows.EXCEPTION_POINTERS, comptime msg: u8, comptime format: ?[]const u8) noreturn { + const exception_address = @ptrToInt(info.ExceptionRecord.ExceptionAddress); + if (comptime windows_exception_context.haveContext) { + const regs = windows_exception_context.getRegs(info.ContextRecord); + 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 const windows_exception_context = switch (builtin.arch) { + .i386 => struct { + pub const haveContext = true; + + pub fn getRegs(ptr: *c_void) struct {bp: usize, ip: usize} { + const ctx = @ptrCast(*const CONTEXT, @alignCast(@alignOf(CONTEXT), ptr)); + return .{.bp = @intCast(usize, ctx.Ebp), .ip = @intCast(usize, ctx.Eip)}; + } + + pub const CONTEXT = extern struct { + ContextFlags: DWORD, + Dr0: DWORD, + Dr1: DWORD, + Dr2: DWORD, + Dr3: DWORD, + Dr6: DWORD, + Dr7: DWORD, + FloatSave: FLOATING_SAVE_AREA, + SegGs: DWORD, + SegFs: DWORD, + SegEs: DWORD, + SegDs: DWORD, + Edi: DWORD, + Esi: DWORD, + Ebx: DWORD, + Edx: DWORD, + Ecx: DWORD, + Eax: DWORD, + Ebp: DWORD, + Eip: DWORD, + SegCs: DWORD, + EFlags: DWORD, + Esp: DWORD, + SegSs: DWORD, + ExtendedRegisters: [512]BYTE, + }; + + pub const FLOATING_SAVE_AREA = extern struct { + ControlWord: DWORD, + StatusWord: DWORD, + TagWord: DWORD, + ErrorOffset: DWORD, + ErrorSelector: DWORD, + DataOffset: DWORD, + DataSelector: DWORD, + RegisterArea: [80]BYTE, + Cr0NpxState: DWORD, + }; + + pub const BYTE = u8; + pub const DWORD = c_ulong; + }, + .x86_64 => struct { + pub const haveContext = true; + + pub fn getRegs(ptr: *c_void) struct {bp: usize, ip: usize} { + const ctx = @ptrCast(*const CONTEXT, @alignCast(@alignOf(CONTEXT), ptr)); + return .{.bp = @intCast(usize, ctx.Rbp), .ip = @intCast(usize, ctx.Rip)}; + } + + pub const CONTEXT = extern struct { + P1Home: DWORD64, + P2Home: DWORD64, + P3Home: DWORD64, + P4Home: DWORD64, + P5Home: DWORD64, + P6Home: DWORD64, + ContextFlags: DWORD, + MxCsr: DWORD, + SegCs: WORD, + SegDs: WORD, + SegEs: WORD, + SegFs: WORD, + SegGs: WORD, + SegSs: WORD, + EFlags: DWORD, + Dr0: DWORD64, + Dr1: DWORD64, + Dr2: DWORD64, + Dr3: DWORD64, + Dr6: DWORD64, + Dr7: DWORD64, + Rax: DWORD64, + Rcx: DWORD64, + Rdx: DWORD64, + Rbx: DWORD64, + Rsp: DWORD64, + Rbp: DWORD64, + Rsi: DWORD64, + Rdi: DWORD64, + R8: DWORD64, + R9: DWORD64, + R10: DWORD64, + R11: DWORD64, + R12: DWORD64, + R13: DWORD64, + R14: DWORD64, + R15: DWORD64, + Rip: DWORD64, + DUMMYUNIONNAME: extern union { + FltSave: XMM_SAVE_AREA32, + FloatSave: XMM_SAVE_AREA32, + DUMMYSTRUCTNAME: extern struct { + Header: [2]M128A, + Legacy: [8]M128A, + Xmm0: M128A, + Xmm1: M128A, + Xmm2: M128A, + Xmm3: M128A, + Xmm4: M128A, + Xmm5: M128A, + Xmm6: M128A, + Xmm7: M128A, + Xmm8: M128A, + Xmm9: M128A, + Xmm10: M128A, + Xmm11: M128A, + Xmm12: M128A, + Xmm13: M128A, + Xmm14: M128A, + Xmm15: M128A, + }, + }, + VectorRegister: [26]M128A, + VectorControl: DWORD64, + DebugControl: DWORD64, + LastBranchToRip: DWORD64, + LastBranchFromRip: DWORD64, + LastExceptionToRip: DWORD64, + LastExceptionFromRip: DWORD64, + }; + + pub const XMM_SAVE_AREA32 = extern struct { + ControlWord: WORD, + StatusWord: WORD, + TagWord: BYTE, + Reserved1: BYTE, + ErrorOpcode: WORD, + ErrorOffset: DWORD, + ErrorSelector: WORD, + Reserved2: WORD, + DataOffset: DWORD, + DataSelector: WORD, + Reserved3: WORD, + MxCsr: DWORD, + MxCsr_Mask: DWORD, + FloatRegisters: [8]M128A, + XmmRegisters: [16]M128A, + Reserved4: [96]BYTE, + }; + + pub const M128A = extern struct { + Low: ULONGLONG, + High: LONGLONG, + }; + + pub const BYTE = u8; + pub const WORD = u16; + pub const DWORD = u32; + pub const DWORD64 = u64; + pub const LONGLONG = c_longlong; + pub const ULONGLONG = c_ulonglong; + }, + .aarch64 => struct { + pub const haveContext = true; + + pub fn getRegs(ptr: *c_void) struct {bp: usize, ip: usize} { + const ctx = @ptrCast(*const CONTEXT, @alignCast(@alignOf(CONTEXT), ptr)); + return .{.bp = @intCast(usize, ctx.Fp), .ip = @intCast(usize, ctx.Pc)}; + } + + pub const CONTEXT = extern struct { + ContextFlags: ULONG, + Cpsr: ULONG, + DUMMYUNIONNAME: extern union { + DUMMYSTRUCTNAME: extern struct { + X0: DWORD64, + X1: DWORD64, + X2: DWORD64, + X3: DWORD64, + X4: DWORD64, + X5: DWORD64, + X6: DWORD64, + X7: DWORD64, + X8: DWORD64, + X9: DWORD64, + X10: DWORD64, + X11: DWORD64, + X12: DWORD64, + X13: DWORD64, + X14: DWORD64, + X15: DWORD64, + X16: DWORD64, + X17: DWORD64, + X18: DWORD64, + X19: DWORD64, + X20: DWORD64, + X21: DWORD64, + X22: DWORD64, + X23: DWORD64, + X24: DWORD64, + X25: DWORD64, + X26: DWORD64, + X27: DWORD64, + X28: DWORD64, + Fp: DWORD64, + Lr: DWORD64, + }, + X: [31]DWORD64, + }, + Sp: DWORD64, + Pc: DWORD64, + V: [32]NEON128, + Fpcr: DWORD, + Fpsr: DWORD, + Bcr: [8]DWORD, + Bvr: [8]DWORD64, + Wcr: [2]DWORD, + Wvr: [2]DWORD64, + }; + + pub const NEON128 = extern union { + DUMMYSTRUCTNAME: extern struct { + Low: ULONGLONG, + High: LONGLONG, + }, + D: [2]f64, + S: [4]f32, + H: [8]WORD, + B: [16]BYTE, + }; + + pub const ULONG = c_ulong; + pub const LONGLONG = c_longlong; + pub const ULONGLONG = c_ulonglong; + pub const BYTE = u8; + pub const WORD = c_ushort; + pub const DWORD = c_ulong; + pub const DWORD64 = c_ulonglong; + }, + else => struct { + pub const haveContext = false; + }, +}; + pub fn dumpStackPointerAddr(prefix: []const u8) void { const sp = asm ("" : [argc] "={rsp}" (-> usize) -- cgit v1.2.3 From b7cd60a354731d61ee3a3184fd4be610382ca1d6 Mon Sep 17 00:00:00 2001 From: Rocknest <35231115+Rocknest@users.noreply.github.com> Date: Wed, 29 Jan 2020 21:09:00 +0200 Subject: Changing stuff and seeing what happens --- lib/std/debug.zig | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib/std/debug.zig') diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 561993fb99..acc3f36412 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -129,7 +129,7 @@ pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void { return; }; const tty_config = detectTTYConfig(); - printSourceAtAddress(debug_info, stderr, ip, tty_config) catch return; + printSourceAtAddress(debug_info, stderr, if (builtin.os == .windows) (ip + 1) else ip, tty_config) catch return; const first_return_address = @intToPtr(*const usize, bp + @sizeOf(usize)).*; printSourceAtAddress(debug_info, stderr, first_return_address - 1, tty_config) catch return; var it = StackIterator{ @@ -325,6 +325,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; } }; -- cgit v1.2.3 From 4a4d6f2be911cae08db434f877a1be2340d262c8 Mon Sep 17 00:00:00 2001 From: Rocknest <35231115+Rocknest@users.noreply.github.com> Date: Wed, 29 Jan 2020 23:15:17 +0200 Subject: Reorganize definitions --- lib/std/debug.zig | 251 +------------------------------------------- lib/std/os/windows/bits.zig | 229 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 230 insertions(+), 250 deletions(-) (limited to 'lib/std/debug.zig') diff --git a/lib/std/debug.zig b/lib/std/debug.zig index acc3f36412..9c1d211805 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -2317,11 +2317,11 @@ fn handleSegfaultWindows(info: *windows.EXCEPTION_POINTERS) callconv(.Stdcall) c } } -// zig won't let me use an anon enum here +// 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 (comptime windows_exception_context.haveContext) { - const regs = windows_exception_context.getRegs(info.ContextRecord); + 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]}), @@ -2341,251 +2341,6 @@ fn handleSegfaultWindowsExtra(info: *windows.EXCEPTION_POINTERS, comptime msg: u } } -pub const windows_exception_context = switch (builtin.arch) { - .i386 => struct { - pub const haveContext = true; - - pub fn getRegs(ptr: *c_void) struct {bp: usize, ip: usize} { - const ctx = @ptrCast(*const CONTEXT, @alignCast(@alignOf(CONTEXT), ptr)); - return .{.bp = @intCast(usize, ctx.Ebp), .ip = @intCast(usize, ctx.Eip)}; - } - - pub const CONTEXT = extern struct { - ContextFlags: DWORD, - Dr0: DWORD, - Dr1: DWORD, - Dr2: DWORD, - Dr3: DWORD, - Dr6: DWORD, - Dr7: DWORD, - FloatSave: FLOATING_SAVE_AREA, - SegGs: DWORD, - SegFs: DWORD, - SegEs: DWORD, - SegDs: DWORD, - Edi: DWORD, - Esi: DWORD, - Ebx: DWORD, - Edx: DWORD, - Ecx: DWORD, - Eax: DWORD, - Ebp: DWORD, - Eip: DWORD, - SegCs: DWORD, - EFlags: DWORD, - Esp: DWORD, - SegSs: DWORD, - ExtendedRegisters: [512]BYTE, - }; - - pub const FLOATING_SAVE_AREA = extern struct { - ControlWord: DWORD, - StatusWord: DWORD, - TagWord: DWORD, - ErrorOffset: DWORD, - ErrorSelector: DWORD, - DataOffset: DWORD, - DataSelector: DWORD, - RegisterArea: [80]BYTE, - Cr0NpxState: DWORD, - }; - - pub const BYTE = u8; - pub const DWORD = c_ulong; - }, - .x86_64 => struct { - pub const haveContext = true; - - pub fn getRegs(ptr: *c_void) struct {bp: usize, ip: usize} { - const ctx = @ptrCast(*const CONTEXT, @alignCast(@alignOf(CONTEXT), ptr)); - return .{.bp = @intCast(usize, ctx.Rbp), .ip = @intCast(usize, ctx.Rip)}; - } - - pub const CONTEXT = extern struct { - P1Home: DWORD64, - P2Home: DWORD64, - P3Home: DWORD64, - P4Home: DWORD64, - P5Home: DWORD64, - P6Home: DWORD64, - ContextFlags: DWORD, - MxCsr: DWORD, - SegCs: WORD, - SegDs: WORD, - SegEs: WORD, - SegFs: WORD, - SegGs: WORD, - SegSs: WORD, - EFlags: DWORD, - Dr0: DWORD64, - Dr1: DWORD64, - Dr2: DWORD64, - Dr3: DWORD64, - Dr6: DWORD64, - Dr7: DWORD64, - Rax: DWORD64, - Rcx: DWORD64, - Rdx: DWORD64, - Rbx: DWORD64, - Rsp: DWORD64, - Rbp: DWORD64, - Rsi: DWORD64, - Rdi: DWORD64, - R8: DWORD64, - R9: DWORD64, - R10: DWORD64, - R11: DWORD64, - R12: DWORD64, - R13: DWORD64, - R14: DWORD64, - R15: DWORD64, - Rip: DWORD64, - DUMMYUNIONNAME: extern union { - FltSave: XMM_SAVE_AREA32, - FloatSave: XMM_SAVE_AREA32, - DUMMYSTRUCTNAME: extern struct { - Header: [2]M128A, - Legacy: [8]M128A, - Xmm0: M128A, - Xmm1: M128A, - Xmm2: M128A, - Xmm3: M128A, - Xmm4: M128A, - Xmm5: M128A, - Xmm6: M128A, - Xmm7: M128A, - Xmm8: M128A, - Xmm9: M128A, - Xmm10: M128A, - Xmm11: M128A, - Xmm12: M128A, - Xmm13: M128A, - Xmm14: M128A, - Xmm15: M128A, - }, - }, - VectorRegister: [26]M128A, - VectorControl: DWORD64, - DebugControl: DWORD64, - LastBranchToRip: DWORD64, - LastBranchFromRip: DWORD64, - LastExceptionToRip: DWORD64, - LastExceptionFromRip: DWORD64, - }; - - pub const XMM_SAVE_AREA32 = extern struct { - ControlWord: WORD, - StatusWord: WORD, - TagWord: BYTE, - Reserved1: BYTE, - ErrorOpcode: WORD, - ErrorOffset: DWORD, - ErrorSelector: WORD, - Reserved2: WORD, - DataOffset: DWORD, - DataSelector: WORD, - Reserved3: WORD, - MxCsr: DWORD, - MxCsr_Mask: DWORD, - FloatRegisters: [8]M128A, - XmmRegisters: [16]M128A, - Reserved4: [96]BYTE, - }; - - pub const M128A = extern struct { - Low: ULONGLONG, - High: LONGLONG, - }; - - pub const BYTE = u8; - pub const WORD = u16; - pub const DWORD = u32; - pub const DWORD64 = u64; - pub const LONGLONG = c_longlong; - pub const ULONGLONG = c_ulonglong; - }, - .aarch64 => struct { - pub const haveContext = true; - - pub fn getRegs(ptr: *c_void) struct {bp: usize, ip: usize} { - const ctx = @ptrCast(*const CONTEXT, @alignCast(@alignOf(CONTEXT), ptr)); - return .{.bp = @intCast(usize, ctx.Fp), .ip = @intCast(usize, ctx.Pc)}; - } - - pub const CONTEXT = extern struct { - ContextFlags: ULONG, - Cpsr: ULONG, - DUMMYUNIONNAME: extern union { - DUMMYSTRUCTNAME: extern struct { - X0: DWORD64, - X1: DWORD64, - X2: DWORD64, - X3: DWORD64, - X4: DWORD64, - X5: DWORD64, - X6: DWORD64, - X7: DWORD64, - X8: DWORD64, - X9: DWORD64, - X10: DWORD64, - X11: DWORD64, - X12: DWORD64, - X13: DWORD64, - X14: DWORD64, - X15: DWORD64, - X16: DWORD64, - X17: DWORD64, - X18: DWORD64, - X19: DWORD64, - X20: DWORD64, - X21: DWORD64, - X22: DWORD64, - X23: DWORD64, - X24: DWORD64, - X25: DWORD64, - X26: DWORD64, - X27: DWORD64, - X28: DWORD64, - Fp: DWORD64, - Lr: DWORD64, - }, - X: [31]DWORD64, - }, - Sp: DWORD64, - Pc: DWORD64, - V: [32]NEON128, - Fpcr: DWORD, - Fpsr: DWORD, - Bcr: [8]DWORD, - Bvr: [8]DWORD64, - Wcr: [2]DWORD, - Wvr: [2]DWORD64, - }; - - pub const NEON128 = extern union { - DUMMYSTRUCTNAME: extern struct { - Low: ULONGLONG, - High: LONGLONG, - }, - D: [2]f64, - S: [4]f32, - H: [8]WORD, - B: [16]BYTE, - }; - - pub const ULONG = c_ulong; - pub const LONGLONG = c_longlong; - pub const ULONGLONG = c_ulonglong; - pub const BYTE = u8; - pub const WORD = c_ushort; - pub const DWORD = c_ulong; - pub const DWORD64 = c_ulonglong; - }, - else => struct { - pub const haveContext = false; - }, -}; - pub fn dumpStackPointerAddr(prefix: []const u8) void { const sp = asm ("" : [argc] "={rsp}" (-> usize) diff --git a/lib/std/os/windows/bits.zig b/lib/std/os/windows/bits.zig index 328732e0c7..e4c685494a 100644 --- a/lib/std/os/windows/bits.zig +++ b/lib/std/os/windows/bits.zig @@ -23,7 +23,6 @@ pub const BOOL = c_int; pub const BOOLEAN = BYTE; pub const BYTE = u8; pub const CHAR = u8; -pub const DWORD = u32; pub const FLOAT = f32; pub const HANDLE = *c_void; pub const HCRYPTPROV = ULONG_PTR; @@ -52,6 +51,8 @@ pub const DWORD_PTR = ULONG_PTR; pub const UNICODE = false; pub const WCHAR = u16; pub const WORD = u16; +pub const DWORD = u32; +pub const DWORD64 = u64; pub const LARGE_INTEGER = i64; pub const USHORT = u16; pub const SHORT = i16; @@ -887,9 +888,233 @@ pub const EXCEPTION_RECORD = extern struct { ExceptionInformation: [15]usize, }; +pub usingnamespace switch (builtin.arch) { + .i386 => struct { + pub const FLOATING_SAVE_AREA = extern struct { + ControlWord: DWORD, + StatusWord: DWORD, + TagWord: DWORD, + ErrorOffset: DWORD, + ErrorSelector: DWORD, + DataOffset: DWORD, + DataSelector: DWORD, + RegisterArea: [80]BYTE, + Cr0NpxState: DWORD, + }; + + pub const CONTEXT = extern struct { + ContextFlags: DWORD, + Dr0: DWORD, + Dr1: DWORD, + Dr2: DWORD, + Dr3: DWORD, + Dr6: DWORD, + Dr7: DWORD, + FloatSave: FLOATING_SAVE_AREA, + SegGs: DWORD, + SegFs: DWORD, + SegEs: DWORD, + SegDs: DWORD, + Edi: DWORD, + Esi: DWORD, + Ebx: DWORD, + Edx: DWORD, + Ecx: DWORD, + Eax: DWORD, + Ebp: DWORD, + Eip: DWORD, + SegCs: DWORD, + EFlags: DWORD, + Esp: DWORD, + SegSs: DWORD, + ExtendedRegisters: [512]BYTE, + + pub fn getRegs(ctx: *const CONTEXT) struct {bp: usize, ip: usize} { + return .{.bp = @intCast(usize, ctx.Ebp), .ip = @intCast(usize, ctx.Eip)}; + } + }; + + pub const PCONTEXT = *CONTEXT; + }, + .x86_64 => struct { + pub const M128A = extern struct { + Low: ULONGLONG, + High: LONGLONG, + }; + + pub const XMM_SAVE_AREA32 = extern struct { + ControlWord: WORD, + StatusWord: WORD, + TagWord: BYTE, + Reserved1: BYTE, + ErrorOpcode: WORD, + ErrorOffset: DWORD, + ErrorSelector: WORD, + Reserved2: WORD, + DataOffset: DWORD, + DataSelector: WORD, + Reserved3: WORD, + MxCsr: DWORD, + MxCsr_Mask: DWORD, + FloatRegisters: [8]M128A, + XmmRegisters: [16]M128A, + Reserved4: [96]BYTE, + }; + + pub const CONTEXT = extern struct { + P1Home: DWORD64, + P2Home: DWORD64, + P3Home: DWORD64, + P4Home: DWORD64, + P5Home: DWORD64, + P6Home: DWORD64, + ContextFlags: DWORD, + MxCsr: DWORD, + SegCs: WORD, + SegDs: WORD, + SegEs: WORD, + SegFs: WORD, + SegGs: WORD, + SegSs: WORD, + EFlags: DWORD, + Dr0: DWORD64, + Dr1: DWORD64, + Dr2: DWORD64, + Dr3: DWORD64, + Dr6: DWORD64, + Dr7: DWORD64, + Rax: DWORD64, + Rcx: DWORD64, + Rdx: DWORD64, + Rbx: DWORD64, + Rsp: DWORD64, + Rbp: DWORD64, + Rsi: DWORD64, + Rdi: DWORD64, + R8: DWORD64, + R9: DWORD64, + R10: DWORD64, + R11: DWORD64, + R12: DWORD64, + R13: DWORD64, + R14: DWORD64, + R15: DWORD64, + Rip: DWORD64, + DUMMYUNIONNAME: extern union { + FltSave: XMM_SAVE_AREA32, + FloatSave: XMM_SAVE_AREA32, + DUMMYSTRUCTNAME: extern struct { + Header: [2]M128A, + Legacy: [8]M128A, + Xmm0: M128A, + Xmm1: M128A, + Xmm2: M128A, + Xmm3: M128A, + Xmm4: M128A, + Xmm5: M128A, + Xmm6: M128A, + Xmm7: M128A, + Xmm8: M128A, + Xmm9: M128A, + Xmm10: M128A, + Xmm11: M128A, + Xmm12: M128A, + Xmm13: M128A, + Xmm14: M128A, + Xmm15: M128A, + }, + }, + VectorRegister: [26]M128A, + VectorControl: DWORD64, + DebugControl: DWORD64, + LastBranchToRip: DWORD64, + LastBranchFromRip: DWORD64, + LastExceptionToRip: DWORD64, + LastExceptionFromRip: DWORD64, + + pub fn getRegs(ctx: *const CONTEXT) struct {bp: usize, ip: usize} { + return .{.bp = @intCast(usize, ctx.Rbp), .ip = @intCast(usize, ctx.Rip)}; + } + }; + + pub const PCONTEXT = *CONTEXT; + }, + .aarch64 => struct { + pub const NEON128 = extern union { + DUMMYSTRUCTNAME: extern struct { + Low: ULONGLONG, + High: LONGLONG, + }, + D: [2]f64, + S: [4]f32, + H: [8]WORD, + B: [16]BYTE, + }; + + pub const CONTEXT = extern struct { + ContextFlags: ULONG, + Cpsr: ULONG, + DUMMYUNIONNAME: extern union { + DUMMYSTRUCTNAME: extern struct { + X0: DWORD64, + X1: DWORD64, + X2: DWORD64, + X3: DWORD64, + X4: DWORD64, + X5: DWORD64, + X6: DWORD64, + X7: DWORD64, + X8: DWORD64, + X9: DWORD64, + X10: DWORD64, + X11: DWORD64, + X12: DWORD64, + X13: DWORD64, + X14: DWORD64, + X15: DWORD64, + X16: DWORD64, + X17: DWORD64, + X18: DWORD64, + X19: DWORD64, + X20: DWORD64, + X21: DWORD64, + X22: DWORD64, + X23: DWORD64, + X24: DWORD64, + X25: DWORD64, + X26: DWORD64, + X27: DWORD64, + X28: DWORD64, + Fp: DWORD64, + Lr: DWORD64, + }, + X: [31]DWORD64, + }, + Sp: DWORD64, + Pc: DWORD64, + V: [32]NEON128, + Fpcr: DWORD, + Fpsr: DWORD, + Bcr: [8]DWORD, + Bvr: [8]DWORD64, + Wcr: [2]DWORD, + Wvr: [2]DWORD64, + + pub fn getRegs(ctx: *const CONTEXT) struct {bp: usize, ip: usize} { + return .{.bp = @intCast(usize, ctx.Fp), .ip = @intCast(usize, ctx.Pc)}; + } + }; + + pub const PCONTEXT = *CONTEXT; + }, + else => struct { + pub const PCONTEXT = *c_void; + }, +}; + pub const EXCEPTION_POINTERS = extern struct { ExceptionRecord: *EXCEPTION_RECORD, - ContextRecord: *c_void, + ContextRecord: PCONTEXT, }; pub const VECTORED_EXCEPTION_HANDLER = fn (ExceptionInfo: *EXCEPTION_POINTERS) callconv(.Stdcall) c_long; -- cgit v1.2.3 From c0c9c601d492e9da3f391ec4d837f7ab02b559df Mon Sep 17 00:00:00 2001 From: Rocknest <35231115+Rocknest@users.noreply.github.com> Date: Wed, 29 Jan 2020 23:48:52 +0200 Subject: Fix off-by-one error --- lib/std/debug.zig | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'lib/std/debug.zig') diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 9c1d211805..2dd1da50c3 100644 --- a/lib/std/debug.zig +++ b/lib/std/debug.zig @@ -129,7 +129,7 @@ pub fn dumpStackTraceFromBase(bp: usize, ip: usize) void { return; }; const tty_config = detectTTYConfig(); - printSourceAtAddress(debug_info, stderr, if (builtin.os == .windows) (ip + 1) else ip, tty_config) catch return; + printSourceAtAddress(debug_info, stderr, ip, tty_config) catch return; const first_return_address = @intToPtr(*const usize, bp + @sizeOf(usize)).*; printSourceAtAddress(debug_info, stderr, first_return_address - 1, tty_config) catch return; var it = StackIterator{ @@ -471,7 +471,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; } } -- cgit v1.2.3 From a5f18c2b2ae86126e0fd0cba67676ae68ba0f1df Mon Sep 17 00:00:00 2001 From: Rocknest <35231115+Rocknest@users.noreply.github.com> Date: Thu, 30 Jan 2020 10:00:28 +0200 Subject: Fix one more edge case --- lib/std/debug.zig | 1 + 1 file changed, 1 insertion(+) (limited to 'lib/std/debug.zig') diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 2dd1da50c3..9cd76cb30c 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, -- cgit v1.2.3