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
17621762 .netbsd => @ptrToInt(info.info.reason.fault.addr),
17631763 else => unreachable,
17641764 };
1765 switch (sig) {
1766 os.SIGSEGV => std.debug.warn("Segmentation fault at address 0x{x}\n", .{addr}),
1767 os.SIGILL => std.debug.warn("Illegal instruction at address 0x{x}\n", .{addr}),
1768 os.SIGBUS => std.debug.warn("Bus error at address 0x{x}\n", .{addr}),
1765
1766 // Don't use std.debug.print() as stderr_mutex may still be locked.
1767 const stderr = io.getStdErr().writer();
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}),
17691772 else => unreachable,
1770 }
1773 } catch os.abort();
1774
17711775 switch (builtin.arch) {
17721776 .i386 => {
17731777 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
18181822 const exception_address = @ptrToInt(info.ExceptionRecord.ExceptionAddress);
18191823 if (@hasDecl(windows, "CONTEXT")) {
18201824 const regs = info.ContextRecord.getRegs();
1821 switch (msg) {
1822 0 => std.debug.warn("{}\n", .{format.?}),
1823 1 => std.debug.warn("Segmentation fault at address 0x{x}\n", .{info.ExceptionRecord.ExceptionInformation[1]}),
1824 2 => std.debug.warn("Illegal instruction at address 0x{x}\n", .{regs.ip}),
1825 // Don't use std.debug.print() as stderr_mutex may still be locked.
1826 const stderr = io.getStdErr().writer();
1827 _ = switch (msg) {
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}),
18251831 else => unreachable,
1826 }
1832 } catch os.abort();
18271833
18281834 dumpStackTraceFromBase(regs.bp, regs.ip);
18291835 os.abort();