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 11:31:38-07:00
logbe2adff087d4fb3ce6f559bf3563bf4ff7dd6df3
treedebcfbe391e54601aab02c36045ea1580bac5cca
parenta6222d1d4bd239530bccf42a1d20b4d48fb94139

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