authorgravatar for zseri.devel@ytrizja.dezseri <zseri.devel@ytrizja.de> 2022-01-21 10:14:44+01:00
committergravatar for git@vexu.euVeikka Tuominen <git@vexu.eu> 2022-03-19 19:13:31+02:00
logc6cf40a0c03822cac3112be58c61ca55d436b5d0
treebbdfd198a258464b23ed84b1534d7f193d646e07
parentd62b1c932e5c5ff9cd3e14b4f3f8c078a0fb43f9

fix sigaction double panic

Fixes #8357

4 files changed, 19 insertions(+), 15 deletions(-)

lib/std/debug.zig+11-6
...@@ -1689,6 +1689,12 @@ pub fn maybeEnableSegfaultHandler() void {...@@ -1689,6 +1689,12 @@ pub fn maybeEnableSegfaultHandler() void {
16891689
1690var windows_segfault_handle: ?windows.HANDLE = null;1690var windows_segfault_handle: ?windows.HANDLE = null;
16911691
1692pub fn updateSegfaultHandler(act: ?*const os.Sigaction) error{OperationNotSupported}!void {
1693 try os.sigaction(os.SIG.SEGV, act, null);
1694 try os.sigaction(os.SIG.ILL, act, null);
1695 try os.sigaction(os.SIG.BUS, act, null);
1696}
1697
1692/// Attaches a global SIGSEGV handler which calls @panic("segmentation fault");1698/// Attaches a global SIGSEGV handler which calls @panic("segmentation fault");
1693pub fn attachSegfaultHandler() void {1699pub fn attachSegfaultHandler() void {
1694 if (!have_segfault_handling_support) {1700 if (!have_segfault_handling_support) {
...@@ -1704,9 +1710,9 @@ pub fn attachSegfaultHandler() void {...@@ -1704,9 +1710,9 @@ pub fn attachSegfaultHandler() void {
1704 .flags = (os.SA.SIGINFO | os.SA.RESTART | os.SA.RESETHAND),1710 .flags = (os.SA.SIGINFO | os.SA.RESTART | os.SA.RESETHAND),
1705 };1711 };
17061712
1707 os.sigaction(os.SIG.SEGV, &act, null);1713 updateSegfaultHandler(&act) catch {
1708 os.sigaction(os.SIG.ILL, &act, null);1714 @panic("unable to install segfault handler, maybe adjust have_segfault_handling_support in std/debug.zig");
1709 os.sigaction(os.SIG.BUS, &act, null);1715 };
1710}1716}
17111717
1712fn resetSegfaultHandler() void {1718fn resetSegfaultHandler() void {
...@@ -1722,9 +1728,8 @@ fn resetSegfaultHandler() void {...@@ -1722,9 +1728,8 @@ fn resetSegfaultHandler() void {
1722 .mask = os.empty_sigset,1728 .mask = os.empty_sigset,
1723 .flags = 0,1729 .flags = 0,
1724 };1730 };
1725 os.sigaction(os.SIG.SEGV, &act, null);1731 // do nothing if an error happens to avoid a double-panic
1726 os.sigaction(os.SIG.ILL, &act, null);1732 updateSegfaultHandler(&act) catch {};
1727 os.sigaction(os.SIG.BUS, &act, null);
1728}1733}
17291734
1730fn handleSegfaultPosix(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const anyopaque) callconv(.C) noreturn {1735fn handleSegfaultPosix(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const anyopaque) callconv(.C) noreturn {
lib/std/os.zig+2-3
...@@ -5521,11 +5521,10 @@ pub fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) SigaltstackError!void {...@@ -5521,11 +5521,10 @@ pub fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) SigaltstackError!void {
5521}5521}
55225522
5523/// Examine and change a signal action.5523/// Examine and change a signal action.
5524pub fn sigaction(sig: u6, act: ?*const Sigaction, oact: ?*Sigaction) void {5524pub fn sigaction(sig: u6, noalias act: ?*const Sigaction, noalias oact: ?*Sigaction) error{OperationNotSupported}!void {
5525 switch (errno(system.sigaction(sig, act, oact))) {5525 switch (errno(system.sigaction(sig, act, oact))) {
5526 .SUCCESS => return,5526 .SUCCESS => return,
5527 .FAULT => unreachable,5527 .INVAL, .NOSYS => return error.OperationNotSupported,
5528 .INVAL => unreachable,
5529 else => unreachable,5528 else => unreachable,
5530 }5529 }
5531}5530}
lib/std/os/test.zig+3-3
...@@ -772,16 +772,16 @@ test "sigaction" {...@@ -772,16 +772,16 @@ test "sigaction" {
772 };772 };
773 var old_sa: os.Sigaction = undefined;773 var old_sa: os.Sigaction = undefined;
774 // Install the new signal handler.774 // Install the new signal handler.
775 os.sigaction(os.SIG.USR1, &sa, null);775 try os.sigaction(os.SIG.USR1, &sa, null);
776 // Check that we can read it back correctly.776 // Check that we can read it back correctly.
777 os.sigaction(os.SIG.USR1, null, &old_sa);777 try os.sigaction(os.SIG.USR1, null, &old_sa);
778 try testing.expectEqual(S.handler, old_sa.handler.sigaction.?);778 try testing.expectEqual(S.handler, old_sa.handler.sigaction.?);
779 try testing.expect((old_sa.flags & os.SA.SIGINFO) != 0);779 try testing.expect((old_sa.flags & os.SA.SIGINFO) != 0);
780 // Invoke the handler.780 // Invoke the handler.
781 try os.raise(os.SIG.USR1);781 try os.raise(os.SIG.USR1);
782 try testing.expect(signal_test_failed == false);782 try testing.expect(signal_test_failed == false);
783 // Check if the handler has been correctly reset to SIG_DFL783 // Check if the handler has been correctly reset to SIG_DFL
784 os.sigaction(os.SIG.USR1, null, &old_sa);784 try os.sigaction(os.SIG.USR1, null, &old_sa);
785 try testing.expectEqual(os.SIG.DFL, old_sa.handler.sigaction);785 try testing.expectEqual(os.SIG.DFL, old_sa.handler.sigaction);
786}786}
787787
src/crash_report.zig+3-3
...@@ -175,9 +175,9 @@ pub fn attachSegfaultHandler() void {...@@ -175,9 +175,9 @@ pub fn attachSegfaultHandler() void {
175 .flags = (os.SA.SIGINFO | os.SA.RESTART | os.SA.RESETHAND),175 .flags = (os.SA.SIGINFO | os.SA.RESTART | os.SA.RESETHAND),
176 };176 };
177177
178 os.sigaction(os.SIG.SEGV, &act, null);178 debug.updateSegfaultHandler(&act) catch {
179 os.sigaction(os.SIG.ILL, &act, null);179 @panic("unable to install segfault handler, maybe adjust have_segfault_handling_support in std/debug.zig");
180 os.sigaction(os.SIG.BUS, &act, null);180 };
181}181}
182182
183fn handleSegfaultPosix(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const anyopaque) callconv(.C) noreturn {183fn handleSegfaultPosix(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const anyopaque) callconv(.C) noreturn {