forked from oven-sh/bun
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcrash_reporter.zig
64 lines (54 loc) · 2.09 KB
/
crash_reporter.zig
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
const std = @import("std");
fn setup_sigactions(act: ?*const os.Sigaction) !void {
try os.sigaction(os.SIG.ABRT, act, null);
try os.sigaction(os.SIG.BUS, act, null);
try os.sigaction(os.SIG.FPE, act, null);
try os.sigaction(os.SIG.ILL, act, null);
try os.sigaction(os.SIG.SEGV, act, null);
try os.sigaction(os.SIG.TRAP, act, null);
}
const builtin = @import("builtin");
const ErrorCallback = *const fn (sig: i32, addr: usize) void;
pub var on_error: ?ErrorCallback = null;
noinline fn sigaction_handler(sig: i32, info: *const std.os.siginfo_t, _: ?*const anyopaque) callconv(.C) void {
// Prevent recursive calls
setup_sigactions(null) catch unreachable;
const addr = switch (builtin.target.os.tag) {
.linux => @intFromPtr(info.fields.sigfault.addr),
.macos, .freebsd => @intFromPtr(info.addr),
.netbsd => @intFromPtr(info.info.reason.fault.addr),
.openbsd => @intFromPtr(info.data.fault.addr),
.solaris => @intFromPtr(info.reason.fault.addr),
else => @compileError("unreachable"),
};
if (on_error) |handle| handle(sig, addr);
}
noinline fn sigpipe_handler(_: i32, _: *const std.os.siginfo_t, _: ?*const anyopaque) callconv(.C) void {
const bun = @import("root").bun;
bun.Output.debug("SIGPIPE received\n", .{});
}
pub fn reloadHandlers() !void {
if (comptime @import("root").bun.Environment.isWindows) {
return @import("root").bun.todo(@src(), {});
}
try os.sigaction(os.SIG.PIPE, null, null);
try setup_sigactions(null);
var act = os.Sigaction{
.handler = .{ .sigaction = sigaction_handler },
.mask = os.empty_sigset,
.flags = (os.SA.SIGINFO | os.SA.RESTART | os.SA.RESETHAND),
};
try setup_sigactions(&act);
bun_ignore_sigpipe();
}
const os = std.os;
pub fn start() !void {
var act = os.Sigaction{
.handler = .{ .sigaction = sigaction_handler },
.mask = os.empty_sigset,
.flags = (os.SA.SIGINFO | os.SA.RESTART | os.SA.RESETHAND),
};
try setup_sigactions(&act);
bun_ignore_sigpipe();
}
extern fn bun_ignore_sigpipe() void;