authorgravatar for thatlemon@gmail.comLemonBoy <thatlemon@gmail.com> 2020-11-28 15:31:26+01:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2020-11-29 10:31:06-08:00
log89ee4b86210dd3292f39e8ab405834a11865833c
tree7aacb38ea122f3178fb38c547b9132f0d6b747ad
parentabc729a5f9da9f4520079507404dd5d299209cba

std: Avoid deadlock in the signal handler

stderr_mutex may still be held when we reach the signal handler, grab our own stderr handle to print the error messages and avoid deadlocking. Closes #7247

1 files changed, 16 insertions(+), 10 deletions(-)

lib/std/debug.zig+16-10
...@@ -1760,12 +1760,16 @@ fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const c_v...@@ -1760,12 +1760,16 @@ fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const c_v
1760 .netbsd => @ptrToInt(info.info.reason.fault.addr),1760 .netbsd => @ptrToInt(info.info.reason.fault.addr),
1761 else => unreachable,1761 else => unreachable,
1762 };1762 };
1763 switch (sig) {1763
1764 os.SIGSEGV => std.debug.warn("Segmentation fault at address 0x{x}\n", .{addr}),1764 // Don't use std.debug.print() as stderr_mutex may still be locked.
1765 os.SIGILL => std.debug.warn("Illegal instruction at address 0x{x}\n", .{addr}),1765 const stderr = io.getStdErr().writer();
1766 os.SIGBUS => std.debug.warn("Bus error at address 0x{x}\n", .{addr}),1766 _ = switch (sig) {
1767 os.SIGSEGV => stderr.print("Segmentation fault at address 0x{x}\n", .{addr}),
1768 os.SIGILL => stderr.print("Illegal instruction at address 0x{x}\n", .{addr}),
1769 os.SIGBUS => stderr.print("Bus error at address 0x{x}\n", .{addr}),
1767 else => unreachable,1770 else => unreachable,
1768 }1771 } catch os.abort();
1772
1769 switch (builtin.arch) {1773 switch (builtin.arch) {
1770 .i386 => {1774 .i386 => {
1771 const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr));1775 const ctx = @ptrCast(*const os.ucontext_t, @alignCast(@alignOf(os.ucontext_t), ctx_ptr));
...@@ -1816,12 +1820,14 @@ fn handleSegfaultWindowsExtra(info: *windows.EXCEPTION_POINTERS, comptime msg: u...@@ -1816,12 +1820,14 @@ fn handleSegfaultWindowsExtra(info: *windows.EXCEPTION_POINTERS, comptime msg: u
1816 const exception_address = @ptrToInt(info.ExceptionRecord.ExceptionAddress);1820 const exception_address = @ptrToInt(info.ExceptionRecord.ExceptionAddress);
1817 if (@hasDecl(windows, "CONTEXT")) {1821 if (@hasDecl(windows, "CONTEXT")) {
1818 const regs = info.ContextRecord.getRegs();1822 const regs = info.ContextRecord.getRegs();
1819 switch (msg) {1823 // Don't use std.debug.print() as stderr_mutex may still be locked.
1820 0 => std.debug.warn("{}\n", .{format.?}),1824 const stderr = io.getStdErr().writer();
1821 1 => std.debug.warn("Segmentation fault at address 0x{x}\n", .{info.ExceptionRecord.ExceptionInformation[1]}),1825 _ = switch (msg) {
1822 2 => std.debug.warn("Illegal instruction at address 0x{x}\n", .{regs.ip}),1826 0 => stderr.print("{s}\n", .{format.?}),
1827 1 => stderr.print("Segmentation fault at address 0x{x}\n", .{info.ExceptionRecord.ExceptionInformation[1]}),
1828 2 => stderr.print("Illegal instruction at address 0x{x}\n", .{regs.ip}),
1823 else => unreachable,1829 else => unreachable,
1824 }1830 } catch os.abort();
18251831
1826 dumpStackTraceFromBase(regs.bp, regs.ip);1832 dumpStackTraceFromBase(regs.bp, regs.ip);
1827 os.abort();1833 os.abort();