Commit 60020fd545

Alex Cameron <ascottcameron@gmail.com>
2020-12-19 11:21:55
Enable segfault handling on FreeBSD.
1 parent d9fe7ea
Changed files (2)
lib
lib/std/os/bits/freebsd.zig
@@ -4,6 +4,7 @@
 // The MIT license requires this copyright notice to be included in all copies
 // and substantial portions of the software.
 const std = @import("../../std.zig");
+const builtin = std.builtin;
 const maxInt = std.math.maxInt;
 
 // See https://svnweb.freebsd.org/base/head/sys/sys/_types.h?view=co
@@ -815,6 +816,53 @@ pub const sigset_t = extern struct {
 
 pub const empty_sigset = sigset_t{ .__bits = [_]u32{0} ** _SIG_WORDS };
 
+pub usingnamespace switch (builtin.arch) {
+    .x86_64 => struct {
+        pub const ucontext_t = extern struct {
+            sigmask: sigset_t,
+            mcontext: mcontext_t,
+            link: ?*ucontext_t,
+            stack: stack_t,
+            flags: c_int,
+            __spare__: [4]c_int,
+        };
+
+        /// XXX x86_64 specific
+        pub const mcontext_t = extern struct {
+            onstack: u64,
+            rdi: u64,
+            rsi: u64,
+            rdx: u64,
+            rcx: u64,
+            r8: u64,
+            r9: u64,
+            rax: u64,
+            rbx: u64,
+            rbp: u64,
+            r10: u64,
+            r11: u64,
+            r12: u64,
+            r13: u64,
+            r14: u64,
+            r15: u64,
+            trapno: u32,
+            fs: u16,
+            gs: u16,
+            addr: u64,
+            flags: u32,
+            es: u16,
+            ds: u16,
+            err: u64,
+            rip: u64,
+            cs: u64,
+            rflags: u64,
+            rsp: u64,
+            ss: u64,
+        };
+    },
+    else => struct {},
+};
+
 pub const EPERM = 1; // Operation not permitted
 pub const ENOENT = 2; // No such file or directory
 pub const ESRCH = 3; // No such process
lib/std/debug.zig
@@ -1696,6 +1696,7 @@ fn getDebugInfoAllocator() *mem.Allocator {
 pub const have_segfault_handling_support = switch (builtin.os.tag) {
     .linux, .netbsd => true,
     .windows => true,
+    .freebsd => @hasDecl(os, "ucontext_t"),
     else => false,
 };
 pub const enable_segfault_handler: bool = if (@hasDecl(root, "enable_segfault_handler"))
@@ -1757,6 +1758,7 @@ fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const c_v
 
     const addr = switch (builtin.os.tag) {
         .linux => @ptrToInt(info.fields.sigfault.addr),
+        .freebsd => @ptrToInt(info.addr),
         .netbsd => @ptrToInt(info.info.reason.fault.addr),
         else => unreachable,
     };
@@ -1781,8 +1783,16 @@ fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const c_v
         },
         .x86_64 => {
             const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr));
-            const ip = @intCast(usize, ctx.mcontext.gregs[os.REG_RIP]);
-            const bp = @intCast(usize, ctx.mcontext.gregs[os.REG_RBP]);
+            const ip = switch (builtin.os.tag) {
+                .linux, .netbsd => @intCast(usize, ctx.mcontext.gregs[os.REG_RIP]),
+                .freebsd => @intCast(usize, ctx.mcontext.rip),
+                else => unreachable,
+            };
+            const bp = switch (builtin.os.tag) {
+                .linux, .netbsd => @intCast(usize, ctx.mcontext.gregs[os.REG_RBP]),
+                .freebsd => @intCast(usize, ctx.mcontext.rbp),
+                else => unreachable,
+            };
             dumpStackTraceFromBase(bp, ip);
         },
         .arm => {