mirror of
https://codeberg.org/ziglang/zig.git
synced 2025-12-07 14:24:43 +00:00
debug: implement segfault handler for macOS aarch64
Tested on a M1 MacBook Pro, macOS Monterey 12.2.
This commit is contained in:
parent
2a415a033c
commit
05cf69209e
4 changed files with 83 additions and 50 deletions
|
|
@ -6,6 +6,26 @@ const native_arch = builtin.target.cpu.arch;
|
||||||
const maxInt = std.math.maxInt;
|
const maxInt = std.math.maxInt;
|
||||||
const iovec_const = std.os.iovec_const;
|
const iovec_const = std.os.iovec_const;
|
||||||
|
|
||||||
|
const arch_bits = switch (native_arch) {
|
||||||
|
.aarch64 => @import("darwin/aarch64.zig"),
|
||||||
|
.x86_64 => @import("darwin/x86_64.zig"),
|
||||||
|
else => struct {},
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const ucontext_t = extern struct {
|
||||||
|
onstack: c_int,
|
||||||
|
sigmask: sigset_t,
|
||||||
|
stack: stack_t,
|
||||||
|
link: ?*ucontext_t,
|
||||||
|
mcsize: u64,
|
||||||
|
mcontext: *mcontext_t,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const mcontext_t = extern struct {
|
||||||
|
es: arch_bits.exception_state,
|
||||||
|
ss: arch_bits.thread_state,
|
||||||
|
};
|
||||||
|
|
||||||
extern "c" fn __error() *c_int;
|
extern "c" fn __error() *c_int;
|
||||||
pub extern "c" fn NSVersionOfRunTimeLibrary(library_name: [*:0]const u8) u32;
|
pub extern "c" fn NSVersionOfRunTimeLibrary(library_name: [*:0]const u8) u32;
|
||||||
pub extern "c" fn _NSGetExecutablePath(buf: [*:0]u8, bufsize: *u32) c_int;
|
pub extern "c" fn _NSGetExecutablePath(buf: [*:0]u8, bufsize: *u32) c_int;
|
||||||
|
|
@ -478,51 +498,6 @@ pub const SIG = struct {
|
||||||
pub const USR2 = 31;
|
pub const USR2 = 31;
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const ucontext_t = extern struct {
|
|
||||||
onstack: c_int,
|
|
||||||
sigmask: sigset_t,
|
|
||||||
stack: stack_t,
|
|
||||||
link: ?*ucontext_t,
|
|
||||||
mcsize: u64,
|
|
||||||
mcontext: *mcontext_t,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const exception_state = extern struct {
|
|
||||||
trapno: u16,
|
|
||||||
cpu: u16,
|
|
||||||
err: u32,
|
|
||||||
faultvaddr: u64,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const thread_state = extern struct {
|
|
||||||
rax: u64,
|
|
||||||
rbx: u64,
|
|
||||||
rcx: u64,
|
|
||||||
rdx: u64,
|
|
||||||
rdi: u64,
|
|
||||||
rsi: u64,
|
|
||||||
rbp: u64,
|
|
||||||
rsp: u64,
|
|
||||||
r8: u64,
|
|
||||||
r9: u64,
|
|
||||||
r10: u64,
|
|
||||||
r11: u64,
|
|
||||||
r12: u64,
|
|
||||||
r13: u64,
|
|
||||||
r14: u64,
|
|
||||||
r15: u64,
|
|
||||||
rip: u64,
|
|
||||||
rflags: u64,
|
|
||||||
cs: u64,
|
|
||||||
fs: u64,
|
|
||||||
gs: u64,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const mcontext_t = extern struct {
|
|
||||||
es: exception_state,
|
|
||||||
ss: thread_state,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub const siginfo_t = extern struct {
|
pub const siginfo_t = extern struct {
|
||||||
signo: c_int,
|
signo: c_int,
|
||||||
errno: c_int,
|
errno: c_int,
|
||||||
|
|
|
||||||
18
lib/std/c/darwin/aarch64.zig
Normal file
18
lib/std/c/darwin/aarch64.zig
Normal file
|
|
@ -0,0 +1,18 @@
|
||||||
|
// See C headers in
|
||||||
|
// lib/libc/include/aarch64-macos.12-gnu/mach/arm/_structs.h
|
||||||
|
|
||||||
|
pub const exception_state = extern struct {
|
||||||
|
far: u64, // Virtual Fault Address
|
||||||
|
esr: u32, // Exception syndrome
|
||||||
|
exception: u32, // Number of arm exception taken
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const thread_state = extern struct {
|
||||||
|
regs: [29]u64, // General purpose registers
|
||||||
|
fp: u64, // Frame pointer x29
|
||||||
|
lr: u64, // Link register x30
|
||||||
|
sp: u64, // Stack pointer x31
|
||||||
|
pc: u64, // Program counter
|
||||||
|
cpsr: u32, // Current program status register
|
||||||
|
__pad: u32,
|
||||||
|
};
|
||||||
30
lib/std/c/darwin/x86_64.zig
Normal file
30
lib/std/c/darwin/x86_64.zig
Normal file
|
|
@ -0,0 +1,30 @@
|
||||||
|
pub const exception_state = extern struct {
|
||||||
|
trapno: u16,
|
||||||
|
cpu: u16,
|
||||||
|
err: u32,
|
||||||
|
faultvaddr: u64,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub const thread_state = extern struct {
|
||||||
|
rax: u64,
|
||||||
|
rbx: u64,
|
||||||
|
rcx: u64,
|
||||||
|
rdx: u64,
|
||||||
|
rdi: u64,
|
||||||
|
rsi: u64,
|
||||||
|
rbp: u64,
|
||||||
|
rsp: u64,
|
||||||
|
r8: u64,
|
||||||
|
r9: u64,
|
||||||
|
r10: u64,
|
||||||
|
r11: u64,
|
||||||
|
r12: u64,
|
||||||
|
r13: u64,
|
||||||
|
r14: u64,
|
||||||
|
r15: u64,
|
||||||
|
rip: u64,
|
||||||
|
rflags: u64,
|
||||||
|
cs: u64,
|
||||||
|
fs: u64,
|
||||||
|
gs: u64,
|
||||||
|
};
|
||||||
|
|
@ -1610,9 +1610,13 @@ fn getDebugInfoAllocator() mem.Allocator {
|
||||||
|
|
||||||
/// Whether or not the current target can print useful debug information when a segfault occurs.
|
/// Whether or not the current target can print useful debug information when a segfault occurs.
|
||||||
pub const have_segfault_handling_support = switch (native_os) {
|
pub const have_segfault_handling_support = switch (native_os) {
|
||||||
.linux, .netbsd, .solaris => true,
|
.linux,
|
||||||
.macos => native_arch == .x86_64,
|
.macos,
|
||||||
.windows => true,
|
.netbsd,
|
||||||
|
.solaris,
|
||||||
|
.windows,
|
||||||
|
=> true,
|
||||||
|
|
||||||
.freebsd, .openbsd => @hasDecl(os.system, "ucontext_t"),
|
.freebsd, .openbsd => @hasDecl(os.system, "ucontext_t"),
|
||||||
else => false,
|
else => false,
|
||||||
};
|
};
|
||||||
|
|
@ -1726,9 +1730,15 @@ fn handleSegfaultPosix(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const any
|
||||||
},
|
},
|
||||||
.aarch64 => {
|
.aarch64 => {
|
||||||
const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr));
|
const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr));
|
||||||
const ip = @intCast(usize, ctx.mcontext.pc);
|
const ip = switch (native_os) {
|
||||||
|
.macos => @intCast(usize, ctx.mcontext.ss.pc),
|
||||||
|
else => @intCast(usize, ctx.mcontext.pc),
|
||||||
|
};
|
||||||
// x29 is the ABI-designated frame pointer
|
// x29 is the ABI-designated frame pointer
|
||||||
const bp = @intCast(usize, ctx.mcontext.regs[29]);
|
const bp = switch (native_os) {
|
||||||
|
.macos => @intCast(usize, ctx.mcontext.ss.fp),
|
||||||
|
else => @intCast(usize, ctx.mcontext.regs[29]),
|
||||||
|
};
|
||||||
dumpStackTraceFromBase(bp, ip);
|
dumpStackTraceFromBase(bp, ip);
|
||||||
},
|
},
|
||||||
else => {},
|
else => {},
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue