Commit be2adff087

LemonBoy <thatlemon@gmail.com>
2020-11-28 15:31:26
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 parent a6222d1
Changed files (1)
lib
lib/std/debug.zig
@@ -1762,12 +1762,16 @@ fn handleSegfaultLinux(sig: i32, info: *const os.siginfo_t, ctx_ptr: ?*const c_v
         .netbsd => @ptrToInt(info.info.reason.fault.addr),
         else => unreachable,
     };
-    switch (sig) {
-        os.SIGSEGV => std.debug.warn("Segmentation fault at address 0x{x}\n", .{addr}),
-        os.SIGILL => std.debug.warn("Illegal instruction at address 0x{x}\n", .{addr}),
-        os.SIGBUS => std.debug.warn("Bus error at address 0x{x}\n", .{addr}),
+
+    // Don't use std.debug.print() as stderr_mutex may still be locked.
+    const stderr = io.getStdErr().writer();
+    _ = switch (sig) {
+        os.SIGSEGV => stderr.print("Segmentation fault at address 0x{x}\n", .{addr}),
+        os.SIGILL => stderr.print("Illegal instruction at address 0x{x}\n", .{addr}),
+        os.SIGBUS => stderr.print("Bus error at address 0x{x}\n", .{addr}),
         else => unreachable,
-    }
+    } catch os.abort();
+
     switch (builtin.arch) {
         .i386 => {
             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
     const exception_address = @ptrToInt(info.ExceptionRecord.ExceptionAddress);
     if (@hasDecl(windows, "CONTEXT")) {
         const regs = info.ContextRecord.getRegs();
-        switch (msg) {
-            0 => std.debug.warn("{}\n", .{format.?}),
-            1 => std.debug.warn("Segmentation fault at address 0x{x}\n", .{info.ExceptionRecord.ExceptionInformation[1]}),
-            2 => std.debug.warn("Illegal instruction at address 0x{x}\n", .{regs.ip}),
+        // Don't use std.debug.print() as stderr_mutex may still be locked.
+        const stderr = io.getStdErr().writer();
+        _ = switch (msg) {
+            0 => stderr.print("{s}\n", .{format.?}),
+            1 => stderr.print("Segmentation fault at address 0x{x}\n", .{info.ExceptionRecord.ExceptionInformation[1]}),
+            2 => stderr.print("Illegal instruction at address 0x{x}\n", .{regs.ip}),
             else => unreachable,
-        }
+        } catch os.abort();
 
         dumpStackTraceFromBase(regs.bp, regs.ip);
         os.abort();