From c9756ca0e16a669263e003b02d21152622db42cc Mon Sep 17 00:00:00 2001 From: LemonBoy Date: Thu, 29 Oct 2020 20:51:37 +0100 Subject: [PATCH] std: Show the panicking thread ID Annotate the panic message with the thread ID to know who's the culprit. --- lib/std/c/darwin.zig | 3 +++ lib/std/c/freebsd.zig | 2 ++ lib/std/c/netbsd.zig | 2 ++ lib/std/c/openbsd.zig | 2 ++ lib/std/debug.zig | 6 ++++++ lib/std/thread.zig | 30 ++++++++++++++++++++++++++++++ 6 files changed, 45 insertions(+) diff --git a/lib/std/c/darwin.zig b/lib/std/c/darwin.zig index 00b7870f28..7527752527 100644 --- a/lib/std/c/darwin.zig +++ b/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. diff --git a/lib/std/c/freebsd.zig b/lib/std/c/freebsd.zig index b4f81d10f0..0eae010d2e 100644 --- a/lib/std/c/freebsd.zig +++ b/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; diff --git a/lib/std/c/netbsd.zig b/lib/std/c/netbsd.zig index bed70deb4f..258ee6a5c6 100644 --- a/lib/std/c/netbsd.zig +++ b/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; diff --git a/lib/std/c/openbsd.zig b/lib/std/c/openbsd.zig index f49db5d67d..f9e0c3c6d8 100644 --- a/lib/std/c/openbsd.zig +++ b/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; diff --git a/lib/std/debug.zig b/lib/std/debug.zig index 10938cb4b0..d67a597031 100644 --- a/lib/std/debug.zig +++ b/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.*); diff --git a/lib/std/thread.zig b/lib/std/thread.zig index 02ca2cb8ac..7d63b5f644 100644 --- a/lib/std/thread.zig +++ b/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"); + }, + } + } };