std.debug: greatly expand target support for segfault handling/unwinding

I made a couple of decisions for this based on the fact that we don't expose the
signal_ucontext_t type outside of the file:

* Adding all the floating point and vector state to every ucontext_t and
  mcontext_t variant was way, way too much work, especially when we don't even
  use the stuff. So I deleted all that and kept only the bare minimum needed to
  reach into general-purpose registers.
* There is no particularly compelling reason to stick to the naming and struct
  nesting used in the system headers. So we can actually unify the access
  patterns for almost all of these variants by taking some liberties here; as a
  result, fromPosixSignalContext() is now much nicer to read and extend.
This commit is contained in:
Alex Rønne Petersen 2025-10-09 09:49:27 +02:00
parent 3f5e782357
commit f33d3a5166
No known key found for this signature in database
3 changed files with 939 additions and 698 deletions

View file

@ -1315,15 +1315,26 @@ fn getDebugInfoAllocator() 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) {
.haiku,
.linux, .linux,
.macos,
.netbsd,
.solaris,
.illumos,
.windows,
.freebsd,
.openbsd,
.serenity, .serenity,
.dragonfly,
.freebsd,
.netbsd,
.openbsd,
.driverkit,
.ios,
.macos,
.tvos,
.visionos,
.watchos,
.illumos,
.solaris,
.windows,
=> true, => true,
else => false, else => false,
@ -1406,11 +1417,26 @@ fn handleSegfaultPosix(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*anyopa
} }
} }
const addr: usize = switch (native_os) { const addr: usize = switch (native_os) {
.linux => @intFromPtr(info.fields.sigfault.addr), .serenity,
.freebsd, .macos, .serenity => @intFromPtr(info.addr), .dragonfly,
.netbsd => @intFromPtr(info.info.reason.fault.addr), .freebsd,
.openbsd => @intFromPtr(info.data.fault.addr), .driverkit,
.solaris, .illumos => @intFromPtr(info.reason.fault.addr), .ios,
.macos,
.tvos,
.visionos,
.watchos,
=> @intFromPtr(info.addr),
.linux,
=> @intFromPtr(info.fields.sigfault.addr),
.netbsd,
=> @intFromPtr(info.info.reason.fault.addr),
.haiku,
.openbsd,
=> @intFromPtr(info.data.fault.addr),
.illumos,
.solaris,
=> @intFromPtr(info.reason.fault.addr),
else => comptime unreachable, else => comptime unreachable,
}; };
const name = switch (sig) { const name = switch (sig) {

View file

@ -94,6 +94,15 @@ pub const can_unwind: bool = s: {
// Notably, we are yet to support unwinding on ARM. There, unwinding is not done through // Notably, we are yet to support unwinding on ARM. There, unwinding is not done through
// `.eh_frame`, but instead with the `.ARM.exidx` section, which has a different format. // `.eh_frame`, but instead with the `.ARM.exidx` section, which has a different format.
const archs: []const std.Target.Cpu.Arch = switch (builtin.target.os.tag) { const archs: []const std.Target.Cpu.Arch = switch (builtin.target.os.tag) {
// Not supported yet: arm, m68k, sparc64
.haiku => &.{
.aarch64,
.powerpc,
.riscv64,
.x86,
.x86_64,
},
// Not supported yet: arc, arm/armeb/thumb/thumbeb, csky, m68k, or1k, sparc/sparc64, xtensa
.linux => &.{ .linux => &.{
.aarch64, .aarch64,
.aarch64_be, .aarch64_be,
@ -113,31 +122,54 @@ pub const can_unwind: bool = s: {
.x86, .x86,
.x86_64, .x86_64,
}, },
.serenity => &.{
.aarch64,
.x86_64,
.riscv64,
},
.dragonfly => &.{
.x86_64,
},
// Not supported yet: arm
.freebsd => &.{
.aarch64,
.powerpc64,
.powerpc64le,
.riscv64,
.x86_64,
},
// Not supported yet: arm/armeb, m68k, mips64/mips64el, sparc/sparc64
.netbsd => &.{ .netbsd => &.{
.aarch64, .aarch64,
.aarch64_be, .aarch64_be,
.mips,
.mipsel,
.powerpc,
.x86, .x86,
.x86_64, .x86_64,
}, },
.freebsd => &.{ // Not supported yet: arm, sparc64
.x86_64,
.aarch64,
},
.openbsd => &.{ .openbsd => &.{
.aarch64,
.mips64,
.mips64el,
.powerpc,
.powerpc64,
.riscv64,
.x86,
.x86_64, .x86_64,
}, },
.solaris => &.{
.x86_64,
},
.illumos => &.{ .illumos => &.{
.x86, .x86,
.x86_64, .x86_64,
}, },
.serenity => &.{ // Not supported yet: sparc64
.solaris => &.{
.x86_64, .x86_64,
.aarch64,
.riscv64,
}, },
else => unreachable, else => unreachable,
}; };
for (archs) |a| { for (archs) |a| {

File diff suppressed because it is too large Load diff