Skip to content

Commit

Permalink
fix sigaction double panic
Browse files Browse the repository at this point in the history
Fixes #8357
  • Loading branch information
fogti authored and Vexu committed Mar 19, 2022
1 parent d62b1c9 commit c6cf40a
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 15 deletions.
17 changes: 11 additions & 6 deletions lib/std/debug.zig
Original file line number Diff line number Diff line change
Expand Up @@ -1689,6 +1689,12 @@ pub fn maybeEnableSegfaultHandler() void {

var windows_segfault_handle: ?windows.HANDLE = null;

pub fn updateSegfaultHandler(act: ?*const os.Sigaction) error{OperationNotSupported}!void {
try os.sigaction(os.SIG.SEGV, act, null);
try os.sigaction(os.SIG.ILL, act, null);
try os.sigaction(os.SIG.BUS, act, null);
}

/// Attaches a global SIGSEGV handler which calls @panic("segmentation fault");
pub fn attachSegfaultHandler() void {
if (!have_segfault_handling_support) {
Expand All @@ -1704,9 +1710,9 @@ pub fn attachSegfaultHandler() void {
.flags = (os.SA.SIGINFO | os.SA.RESTART | os.SA.RESETHAND),
};

os.sigaction(os.SIG.SEGV, &act, null);
os.sigaction(os.SIG.ILL, &act, null);
os.sigaction(os.SIG.BUS, &act, null);
updateSegfaultHandler(&act) catch {
@panic("unable to install segfault handler, maybe adjust have_segfault_handling_support in std/debug.zig");
};
}

fn resetSegfaultHandler() void {
Expand All @@ -1722,9 +1728,8 @@ fn resetSegfaultHandler() void {
.mask = os.empty_sigset,
.flags = 0,
};
os.sigaction(os.SIG.SEGV, &act, null);
os.sigaction(os.SIG.ILL, &act, null);
os.sigaction(os.SIG.BUS, &act, null);
// do nothing if an error happens to avoid a double-panic
updateSegfaultHandler(&act) catch {};
}

fn handleSegfaultPosix(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const anyopaque) callconv(.C) noreturn {
Expand Down
5 changes: 2 additions & 3 deletions lib/std/os.zig
Original file line number Diff line number Diff line change
Expand Up @@ -5521,11 +5521,10 @@ pub fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) SigaltstackError!void {
}

/// Examine and change a signal action.
pub fn sigaction(sig: u6, act: ?*const Sigaction, oact: ?*Sigaction) void {
pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) error{OperationNotSupported}!void {
switch (errno(system.sigaction(sig, act, oact))) {
.SUCCESS => return,
.FAULT => unreachable,
.INVAL => unreachable,
.INVAL, .NOSYS => return error.OperationNotSupported,
else => unreachable,
}
}
Expand Down
6 changes: 3 additions & 3 deletions lib/std/os/test.zig
Original file line number Diff line number Diff line change
Expand Up @@ -772,16 +772,16 @@ test "sigaction" {
};
var old_sa: os.Sigaction = undefined;
// Install the new signal handler.
os.sigaction(os.SIG.USR1, &sa, null);
try os.sigaction(os.SIG.USR1, &sa, null);
// Check that we can read it back correctly.
os.sigaction(os.SIG.USR1, null, &old_sa);
try os.sigaction(os.SIG.USR1, null, &old_sa);
try testing.expectEqual(S.handler, old_sa.handler.sigaction.?);
try testing.expect((old_sa.flags & os.SA.SIGINFO) != 0);
// Invoke the handler.
try os.raise(os.SIG.USR1);
try testing.expect(signal_test_failed == false);
// Check if the handler has been correctly reset to SIG_DFL
os.sigaction(os.SIG.USR1, null, &old_sa);
try os.sigaction(os.SIG.USR1, null, &old_sa);
try testing.expectEqual(os.SIG.DFL, old_sa.handler.sigaction);
}

Expand Down
6 changes: 3 additions & 3 deletions src/crash_report.zig
Original file line number Diff line number Diff line change
Expand Up @@ -175,9 +175,9 @@ pub fn attachSegfaultHandler() void {
.flags = (os.SA.SIGINFO | os.SA.RESTART | os.SA.RESETHAND),
};

os.sigaction(os.SIG.SEGV, &act, null);
os.sigaction(os.SIG.ILL, &act, null);
os.sigaction(os.SIG.BUS, &act, null);
debug.updateSegfaultHandler(&act) catch {
@panic("unable to install segfault handler, maybe adjust have_segfault_handling_support in std/debug.zig");
};
}

fn handleSegfaultPosix(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const anyopaque) callconv(.C) noreturn {
Expand Down

0 comments on commit c6cf40a

Please sign in to comment.