Commit c9756ca0e1

LemonBoy <thatlemon@gmail.com>
2020-10-29 20:51:37
std: Show the panicking thread ID
Annotate the panic message with the thread ID to know who's the culprit.
1 parent 3bce5b2
lib/std/c/darwin.zig
@@ -186,6 +186,9 @@ pub const pthread_attr_t = extern struct {
     __opaque: [56]u8,
 };
 
+const pthread_t = std.c.pthread_t;
+pub extern "c" fn pthread_threadid_np(thread: ?pthread_t, thread_id: *u64) c_int;
+
 pub extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void;
 
 // Grand Central Dispatch is exposed by libSystem.
lib/std/c/freebsd.zig
@@ -13,6 +13,8 @@ pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;
 pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
 pub extern "c" fn getrandom(buf_ptr: [*]u8, buf_len: usize, flags: c_uint) isize;
 
+pub extern "pthread" fn pthread_getthreadid_np() c_int;
+
 pub extern "c" fn posix_memalign(memptr: *?*c_void, alignment: usize, size: usize) c_int;
 pub extern "c" fn malloc_usable_size(?*const c_void) usize;
 
lib/std/c/netbsd.zig
@@ -14,6 +14,8 @@ pub const _errno = __errno;
 pub const dl_iterate_phdr_callback = fn (info: *dl_phdr_info, size: usize, data: ?*c_void) callconv(.C) c_int;
 pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_void) c_int;
 
+pub extern "c" fn _lwp_self() lwpid_t;
+
 pub extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void;
 pub extern "c" fn __fstat50(fd: fd_t, buf: *Stat) c_int;
 pub extern "c" fn __stat50(path: [*:0]const u8, buf: *Stat) c_int;
lib/std/c/openbsd.zig
@@ -16,6 +16,8 @@ pub extern "c" fn dl_iterate_phdr(callback: dl_iterate_phdr_callback, data: ?*c_
 
 pub extern "c" fn arc4random_buf(buf: [*]u8, len: usize) void;
 
+pub extern "c" fn getthrid() pid_t;
+
 pub extern "c" fn getdents(fd: c_int, buf_ptr: [*]u8, nbytes: usize) usize;
 pub extern "c" fn sigaltstack(ss: ?*stack_t, old_ss: ?*stack_t) c_int;
 
lib/std/debug.zig
@@ -262,6 +262,12 @@ pub fn panicExtra(trace: ?*const builtin.StackTrace, first_trace_addr: ?usize, c
                 defer held.release();
 
                 const stderr = io.getStdErr().writer();
+                if (builtin.single_threaded) {
+                    stderr.print("main thread panicked: ", .{}) catch os.abort();
+                } else {
+                    const current_thread_id = std.Thread.getCurrentThreadId();
+                    stderr.print("thread {d} panicked: ", .{current_thread_id}) catch os.abort();
+                }
                 stderr.print(format ++ "\n", args) catch os.abort();
                 if (trace) |t| {
                     dumpStackTrace(t.*);
lib/std/thread.zig
@@ -493,4 +493,34 @@ pub const Thread = struct {
         };
         return @intCast(usize, count);
     }
+
+    pub fn getCurrentThreadId() u64 {
+        switch (std.Target.current.os.tag) {
+            .linux => {
+                // Use the syscall directly as musl doesn't provide a wrapper.
+                return @bitCast(u32, os.linux.gettid());
+            },
+            .windows => {
+                return os.windows.kernel32.GetCurrentThreadId();
+            },
+            .macos, .ios, .watchos, .tvos => {
+                var thread_id: u64 = undefined;
+                // Pass thread=null to get the current thread ID.
+                assert(c.pthread_threadid_np(null, &thread_id) == 0);
+                return thread_id;
+            },
+            .netbsd => {
+                return @bitCast(u32, c._lwp_self());
+            },
+            .freebsd => {
+                return @bitCast(u32, c.pthread_getthreadid_np());
+            },
+            .openbsd => {
+                return @bitCast(u32, c.getthrid());
+            },
+            else => {
+                @compileError("getCurrentThreadId not implemented for this platform");
+            },
+        }
+    }
 };