| ... | @@ -203,53 +203,11 @@ fn handleSegfaultPosix(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const any | ... | @@ -203,53 +203,11 @@ fn handleSegfaultPosix(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const any |
| 203 | }; | 203 | }; |
| 204 | | 204 | |
| 205 | const stack_ctx: StackContext = switch (builtin.cpu.arch) { | 205 | const stack_ctx: StackContext = switch (builtin.cpu.arch) { |
| 206 | .x86 => ctx: { | 206 | .x86, |
| 207 | const ctx: *const os.ucontext_t = @ptrCast(@alignCast(ctx_ptr)); | 207 | .x86_64, |
| 208 | const ip = @as(usize, @intCast(ctx.mcontext.gregs[os.REG.EIP])); | 208 | .arm, |
| 209 | const bp = @as(usize, @intCast(ctx.mcontext.gregs[os.REG.EBP])); | 209 | .aarch64, |
| 210 | break :ctx StackContext{ .exception = .{ .bp = bp, .ip = ip } }; | 210 | => StackContext{ .exception = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr)) }, |
| 211 | }, | | |
| 212 | .x86_64 => ctx: { | | |
| 213 | const ctx: *const os.ucontext_t = @ptrCast(@alignCast(ctx_ptr)); | | |
| 214 | const ip = switch (builtin.os.tag) { | | |
| 215 | .linux, .netbsd, .solaris => @as(usize, @intCast(ctx.mcontext.gregs[os.REG.RIP])), | | |
| 216 | .freebsd => @as(usize, @intCast(ctx.mcontext.rip)), | | |
| 217 | .openbsd => @as(usize, @intCast(ctx.sc_rip)), | | |
| 218 | .macos => @as(usize, @intCast(ctx.mcontext.ss.rip)), | | |
| 219 | else => unreachable, | | |
| 220 | }; | | |
| 221 | const bp = switch (builtin.os.tag) { | | |
| 222 | .linux, .netbsd, .solaris => @as(usize, @intCast(ctx.mcontext.gregs[os.REG.RBP])), | | |
| 223 | .openbsd => @as(usize, @intCast(ctx.sc_rbp)), | | |
| 224 | .freebsd => @as(usize, @intCast(ctx.mcontext.rbp)), | | |
| 225 | .macos => @as(usize, @intCast(ctx.mcontext.ss.rbp)), | | |
| 226 | else => unreachable, | | |
| 227 | }; | | |
| 228 | break :ctx StackContext{ .exception = .{ .bp = bp, .ip = ip } }; | | |
| 229 | }, | | |
| 230 | .arm => ctx: { | | |
| 231 | const ctx: *const os.ucontext_t = @ptrCast(@alignCast(ctx_ptr)); | | |
| 232 | const ip = @as(usize, @intCast(ctx.mcontext.arm_pc)); | | |
| 233 | const bp = @as(usize, @intCast(ctx.mcontext.arm_fp)); | | |
| 234 | break :ctx StackContext{ .exception = .{ .bp = bp, .ip = ip } }; | | |
| 235 | }, | | |
| 236 | .aarch64 => ctx: { | | |
| 237 | const ctx: *const os.ucontext_t = @ptrCast(@alignCast(ctx_ptr)); | | |
| 238 | const ip = switch (native_os) { | | |
| 239 | .macos => @as(usize, @intCast(ctx.mcontext.ss.pc)), | | |
| 240 | .netbsd => @as(usize, @intCast(ctx.mcontext.gregs[os.REG.PC])), | | |
| 241 | .freebsd => @as(usize, @intCast(ctx.mcontext.gpregs.elr)), | | |
| 242 | else => @as(usize, @intCast(ctx.mcontext.pc)), | | |
| 243 | }; | | |
| 244 | // x29 is the ABI-designated frame pointer | | |
| 245 | const bp = switch (native_os) { | | |
| 246 | .macos => @as(usize, @intCast(ctx.mcontext.ss.fp)), | | |
| 247 | .netbsd => @as(usize, @intCast(ctx.mcontext.gregs[os.REG.FP])), | | |
| 248 | .freebsd => @as(usize, @intCast(ctx.mcontext.gpregs.x[os.REG.FP])), | | |
| 249 | else => @as(usize, @intCast(ctx.mcontext.regs[29])), | | |
| 250 | }; | | |
| 251 | break :ctx StackContext{ .exception = .{ .bp = bp, .ip = ip } }; | | |
| 252 | }, | | |
| 253 | else => .not_supported, | 211 | else => .not_supported, |
| 254 | }; | 212 | }; |
| 255 | | 213 | |
| ... | @@ -277,7 +235,7 @@ fn handleSegfaultWindowsExtra(info: *os.windows.EXCEPTION_POINTERS, comptime msg | ... | @@ -277,7 +235,7 @@ fn handleSegfaultWindowsExtra(info: *os.windows.EXCEPTION_POINTERS, comptime msg |
| 277 | | 235 | |
| 278 | const stack_ctx = if (@hasDecl(os.windows, "CONTEXT")) ctx: { | 236 | const stack_ctx = if (@hasDecl(os.windows, "CONTEXT")) ctx: { |
| 279 | const regs = info.ContextRecord.getRegs(); | 237 | const regs = info.ContextRecord.getRegs(); |
| 280 | break :ctx StackContext{ .exception = .{ .bp = regs.bp, .ip = regs.ip } }; | 238 | break :ctx StackContext{ .exception = regs }; |
| 281 | } else ctx: { | 239 | } else ctx: { |
| 282 | const addr = @intFromPtr(info.ExceptionRecord.ExceptionAddress); | 240 | const addr = @intFromPtr(info.ExceptionRecord.ExceptionAddress); |
| 283 | break :ctx StackContext{ .current = .{ .ret_addr = addr } }; | 241 | break :ctx StackContext{ .current = .{ .ret_addr = addr } }; |
| ... | @@ -314,10 +272,7 @@ const StackContext = union(enum) { | ... | @@ -314,10 +272,7 @@ const StackContext = union(enum) { |
| 314 | current: struct { | 272 | current: struct { |
| 315 | ret_addr: ?usize, | 273 | ret_addr: ?usize, |
| 316 | }, | 274 | }, |
| 317 | exception: struct { | 275 | exception: debug.StackTraceContext, |
| 318 | bp: usize, | | |
| 319 | ip: usize, | | |
| 320 | }, | | |
| 321 | not_supported: void, | 276 | not_supported: void, |
| 322 | | 277 | |
| 323 | pub fn dumpStackTrace(ctx: @This()) void { | 278 | pub fn dumpStackTrace(ctx: @This()) void { |
| ... | @@ -325,8 +280,8 @@ const StackContext = union(enum) { | ... | @@ -325,8 +280,8 @@ const StackContext = union(enum) { |
| 325 | .current => |ct| { | 280 | .current => |ct| { |
| 326 | debug.dumpCurrentStackTrace(ct.ret_addr); | 281 | debug.dumpCurrentStackTrace(ct.ret_addr); |
| 327 | }, | 282 | }, |
| 328 | .exception => |ex| { | 283 | .exception => |context| { |
| 329 | debug.dumpStackTraceFromBase(ex.bp, ex.ip); | 284 | debug.dumpStackTraceFromBase(context); |
| 330 | }, | 285 | }, |
| 331 | .not_supported => { | 286 | .not_supported => { |
| 332 | const stderr = io.getStdErr().writer(); | 287 | const stderr = io.getStdErr().writer(); |