refactor: port to writergate

This commit is contained in:
CJ van den Berg 2025-08-05 20:11:35 +02:00
parent dfd3c5d66e
commit e558502ea2
Signed by: neurocyte
GPG key ID: 8EB1E1BB660E3FB9
5 changed files with 70 additions and 44 deletions

View file

@ -156,7 +156,10 @@ fn handle_crash(sig: i32, info: *const std.posix.siginfo_t, ctx_ptr: ?*anyopaque
self.tty.deinit();
}
if (builtin.os.tag == .linux and jit_debugger_enabled) {
handleSegfaultPosixNoAbort(sig, info, ctx_ptr);
var buf: [4096]u8 = undefined;
var stderr = std.fs.File.stderr().writer(&buf);
defer stderr.interface.flush() catch {};
handleSegfaultPosixNoAbort(&stderr.interface, sig, info, ctx_ptr);
@import("thespian").sighdl_debugger(sig, @ptrCast(@constCast(info)), ctx_ptr);
std.posix.abort();
} else {
@ -165,7 +168,7 @@ fn handle_crash(sig: i32, info: *const std.posix.siginfo_t, ctx_ptr: ?*anyopaque
unreachable;
}
fn handleSegfaultPosixNoAbort(sig: i32, info: *const std.posix.siginfo_t, ctx_ptr: ?*anyopaque) void {
fn handleSegfaultPosixNoAbort(stderr: *std.io.Writer, sig: i32, info: *const std.posix.siginfo_t, ctx_ptr: ?*anyopaque) void {
const debug = @import("std/debug.zig");
debug.resetSegfaultHandler();
const addr = switch (builtin.os.tag) {
@ -177,7 +180,7 @@ fn handleSegfaultPosixNoAbort(sig: i32, info: *const std.posix.siginfo_t, ctx_pt
else => unreachable,
};
const code = if (builtin.os.tag == .netbsd) info.info.code else info.code;
debug.dumpSegfaultInfoPosix(sig, code, addr, ctx_ptr);
debug.dumpSegfaultInfoPosix(stderr, sig, code, addr, ctx_ptr);
}
pub fn run(self: *Self) Error!void {

View file

@ -384,16 +384,14 @@ pub inline fn getContext(context: *ThreadContext) bool {
/// Tries to print the stack trace starting from the supplied base pointer to stderr,
/// unbuffered, and ignores any error returned.
/// TODO multithreaded awareness
pub fn dumpStackTraceFromBase(context: *ThreadContext) void {
pub fn dumpStackTraceFromBase(stderr: *io.Writer, context: *ThreadContext) void {
nosuspend {
if (builtin.target.cpu.arch.isWasm()) {
if (native_os == .wasi) {
const stderr = io.getStdErr().writer();
stderr.print("Unable to dump stack trace: not implemented for Wasm\n", .{}) catch return;
}
return;
}
const stderr = io.getStdErr().writer();
if (builtin.strip_debug_info) {
stderr.print("Unable to dump stack trace: debug info stripped\n", .{}) catch return;
return;
@ -402,7 +400,7 @@ pub fn dumpStackTraceFromBase(context: *ThreadContext) void {
stderr.print("Unable to dump stack trace: Unable to open debug info: {s}\n", .{@errorName(err)}) catch return;
return;
};
const tty_config = io.tty.detectConfig(io.getStdErr());
const tty_config = io.tty.detectConfig(fs.File.stderr());
if (native_os == .windows) {
// On x86_64 and aarch64, the stack will be unwound using RtlVirtualUnwind using the context
// provided by the exception handler. On x86, RtlVirtualUnwind doesn't exist. Instead, a new backtrace
@ -1425,14 +1423,22 @@ pub fn handleSegfaultPosix(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*an
lockStdErr();
defer unlockStdErr();
dumpSegfaultInfoPosix(sig, code, addr, ctx_ptr);
var buf: [4096]u8 = undefined;
var stderr = fs.File.stderr().writer(&buf);
defer stderr.interface.flush() catch {};
dumpSegfaultInfoPosix(&stderr.interface, sig, code, addr, ctx_ptr);
}
waitForOtherThreadToFinishPanicking();
},
else => {
var buf: [4096]u8 = undefined;
var stderr = fs.File.stderr().writer(&buf);
defer stderr.interface.flush() catch {};
// panic mutex already locked
dumpSegfaultInfoPosix(sig, code, addr, ctx_ptr);
dumpSegfaultInfoPosix(&stderr.interface, sig, code, addr, ctx_ptr);
},
};
@ -1442,8 +1448,7 @@ pub fn handleSegfaultPosix(sig: i32, info: *const posix.siginfo_t, ctx_ptr: ?*an
posix.abort();
}
pub fn dumpSegfaultInfoPosix(sig: i32, code: i32, addr: usize, ctx_ptr: ?*anyopaque) void {
const stderr = io.getStdErr().writer();
pub fn dumpSegfaultInfoPosix(stderr: *io.Writer, sig: i32, code: i32, addr: usize, ctx_ptr: ?*anyopaque) void {
_ = switch (sig) {
posix.SIG.SEGV => if (native_arch == .x86_64 and native_os == .linux and code == 128) // SI_KERNEL
// x86_64 doesn't have a full 64-bit virtual address space.
@ -1491,7 +1496,7 @@ pub fn dumpSegfaultInfoPosix(sig: i32, code: i32, addr: usize, ctx_ptr: ?*anyopa
}, @ptrCast(ctx)).__mcontext_data;
}
relocateContext(&new_ctx);
dumpStackTraceFromBase(&new_ctx);
dumpStackTraceFromBase(stderr, &new_ctx);
},
else => {},
}