mirror of
https://github.com/ziglang/zig.git
synced 2026-02-21 16:54:52 +00:00
debug: use an explicit context type instead of anytype for dumpStackTraceFromBase, update crash_report to use this for exceptions
This commit is contained in:
parent
d74c8acdfb
commit
2f75d20d87
@ -133,11 +133,20 @@ pub fn dumpCurrentStackTrace(start_addr: ?usize) void {
|
||||
}
|
||||
}
|
||||
|
||||
pub const StackTraceContext = blk: {
|
||||
if (native_os == .windows) {
|
||||
break :blk @typeInfo(@TypeOf(os.windows.CONTEXT.getRegs)).Fn.return_type.?;
|
||||
} else if (@hasDecl(os.system, "ucontext_t")) {
|
||||
break :blk *const os.ucontext_t;
|
||||
} else {
|
||||
break :blk void;
|
||||
}
|
||||
};
|
||||
|
||||
/// Tries to print the stack trace starting from the supplied base pointer to stderr,
|
||||
/// unbuffered, and ignores any error returned.
|
||||
/// `context` is either *const os.ucontext_t on posix, or the result of CONTEXT.getRegs() on Windows.
|
||||
/// TODO multithreaded awareness
|
||||
pub fn dumpStackTraceFromBase(context: anytype) void {
|
||||
pub fn dumpStackTraceFromBase(context: StackTraceContext) void {
|
||||
nosuspend {
|
||||
if (comptime builtin.target.isWasm()) {
|
||||
if (native_os == .wasi) {
|
||||
|
||||
@ -203,53 +203,11 @@ fn handleSegfaultPosix(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const any
|
||||
};
|
||||
|
||||
const stack_ctx: StackContext = switch (builtin.cpu.arch) {
|
||||
.x86 => ctx: {
|
||||
const ctx: *const os.ucontext_t = @ptrCast(@alignCast(ctx_ptr));
|
||||
const ip = @as(usize, @intCast(ctx.mcontext.gregs[os.REG.EIP]));
|
||||
const bp = @as(usize, @intCast(ctx.mcontext.gregs[os.REG.EBP]));
|
||||
break :ctx StackContext{ .exception = .{ .bp = bp, .ip = ip } };
|
||||
},
|
||||
.x86_64 => ctx: {
|
||||
const ctx: *const os.ucontext_t = @ptrCast(@alignCast(ctx_ptr));
|
||||
const ip = switch (builtin.os.tag) {
|
||||
.linux, .netbsd, .solaris => @as(usize, @intCast(ctx.mcontext.gregs[os.REG.RIP])),
|
||||
.freebsd => @as(usize, @intCast(ctx.mcontext.rip)),
|
||||
.openbsd => @as(usize, @intCast(ctx.sc_rip)),
|
||||
.macos => @as(usize, @intCast(ctx.mcontext.ss.rip)),
|
||||
else => unreachable,
|
||||
};
|
||||
const bp = switch (builtin.os.tag) {
|
||||
.linux, .netbsd, .solaris => @as(usize, @intCast(ctx.mcontext.gregs[os.REG.RBP])),
|
||||
.openbsd => @as(usize, @intCast(ctx.sc_rbp)),
|
||||
.freebsd => @as(usize, @intCast(ctx.mcontext.rbp)),
|
||||
.macos => @as(usize, @intCast(ctx.mcontext.ss.rbp)),
|
||||
else => unreachable,
|
||||
};
|
||||
break :ctx StackContext{ .exception = .{ .bp = bp, .ip = ip } };
|
||||
},
|
||||
.arm => ctx: {
|
||||
const ctx: *const os.ucontext_t = @ptrCast(@alignCast(ctx_ptr));
|
||||
const ip = @as(usize, @intCast(ctx.mcontext.arm_pc));
|
||||
const bp = @as(usize, @intCast(ctx.mcontext.arm_fp));
|
||||
break :ctx StackContext{ .exception = .{ .bp = bp, .ip = ip } };
|
||||
},
|
||||
.aarch64 => ctx: {
|
||||
const ctx: *const os.ucontext_t = @ptrCast(@alignCast(ctx_ptr));
|
||||
const ip = switch (native_os) {
|
||||
.macos => @as(usize, @intCast(ctx.mcontext.ss.pc)),
|
||||
.netbsd => @as(usize, @intCast(ctx.mcontext.gregs[os.REG.PC])),
|
||||
.freebsd => @as(usize, @intCast(ctx.mcontext.gpregs.elr)),
|
||||
else => @as(usize, @intCast(ctx.mcontext.pc)),
|
||||
};
|
||||
// x29 is the ABI-designated frame pointer
|
||||
const bp = switch (native_os) {
|
||||
.macos => @as(usize, @intCast(ctx.mcontext.ss.fp)),
|
||||
.netbsd => @as(usize, @intCast(ctx.mcontext.gregs[os.REG.FP])),
|
||||
.freebsd => @as(usize, @intCast(ctx.mcontext.gpregs.x[os.REG.FP])),
|
||||
else => @as(usize, @intCast(ctx.mcontext.regs[29])),
|
||||
};
|
||||
break :ctx StackContext{ .exception = .{ .bp = bp, .ip = ip } };
|
||||
},
|
||||
.x86,
|
||||
.x86_64,
|
||||
.arm,
|
||||
.aarch64,
|
||||
=> StackContext{ .exception = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr)) },
|
||||
else => .not_supported,
|
||||
};
|
||||
|
||||
@ -277,7 +235,7 @@ fn handleSegfaultWindowsExtra(info: *os.windows.EXCEPTION_POINTERS, comptime msg
|
||||
|
||||
const stack_ctx = if (@hasDecl(os.windows, "CONTEXT")) ctx: {
|
||||
const regs = info.ContextRecord.getRegs();
|
||||
break :ctx StackContext{ .exception = .{ .bp = regs.bp, .ip = regs.ip } };
|
||||
break :ctx StackContext{ .exception = regs };
|
||||
} else ctx: {
|
||||
const addr = @intFromPtr(info.ExceptionRecord.ExceptionAddress);
|
||||
break :ctx StackContext{ .current = .{ .ret_addr = addr } };
|
||||
@ -314,10 +272,7 @@ const StackContext = union(enum) {
|
||||
current: struct {
|
||||
ret_addr: ?usize,
|
||||
},
|
||||
exception: struct {
|
||||
bp: usize,
|
||||
ip: usize,
|
||||
},
|
||||
exception: debug.StackTraceContext,
|
||||
not_supported: void,
|
||||
|
||||
pub fn dumpStackTrace(ctx: @This()) void {
|
||||
@ -325,8 +280,8 @@ const StackContext = union(enum) {
|
||||
.current => |ct| {
|
||||
debug.dumpCurrentStackTrace(ct.ret_addr);
|
||||
},
|
||||
.exception => |ex| {
|
||||
debug.dumpStackTraceFromBase(ex.bp, ex.ip);
|
||||
.exception => |context| {
|
||||
debug.dumpStackTraceFromBase(context);
|
||||
},
|
||||
.not_supported => {
|
||||
const stderr = io.getStdErr().writer();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user