Index: lib/libthr/thread/thr_cond.c =================================================================== --- lib/libthr/thread/thr_cond.c +++ lib/libthr/thread/thr_cond.c @@ -259,7 +259,7 @@ curthread = _get_curthread(); if (curthread->wchan != NULL) - PANIC("thread was already on queue."); + PANIC("thread %p was already on queue.", curthread); if (cancel) _thr_testcancel(curthread); Index: lib/libthr/thread/thr_exit.c =================================================================== --- lib/libthr/thread/thr_exit.c +++ lib/libthr/thread/thr_exit.c @@ -35,6 +35,7 @@ #ifdef _PTHREAD_FORCED_UNWIND #include #endif +#include #include #include #include @@ -172,18 +173,31 @@ #endif void -_thread_exit(const char *fname, int lineno, const char *msg) +_thread_exitf(const char *fname, int lineno, const char *fmt, ...) { + va_list ap; /* Write an error message to the standard error file descriptor: */ - _thread_printf(2, - "Fatal error '%s' at line %d in file %s (errno = %d)\n", - msg, lineno, fname, errno); + _thread_printf(2, "Fatal error '"); + + va_start(ap, fmt); + _thread_vprintf(2, fmt, ap); + va_end(ap); + + _thread_printf(2, "' at line %d in file %s (errno = %d)\n", lineno, + fname, errno); abort(); } void +_thread_exit(const char *fname, int lineno, const char *msg) +{ + + _thread_exitf(fname, lineno, "%s", msg); +} + +void _pthread_exit(void *status) { _pthread_exit_mask(status, NULL); @@ -195,13 +209,10 @@ struct pthread *curthread = _get_curthread(); /* Check if this thread is already in the process of exiting: */ - if (curthread->cancelling) { - char msg[128]; - snprintf(msg, sizeof(msg), "Thread %p has called " + if (curthread->cancelling) + PANIC("Thread %p has called " "pthread_exit() from a destructor. POSIX 1003.1 " "1996 s16.2.5.2 does not allow this!", curthread); - PANIC(msg); - } /* Flag this thread as exiting. */ curthread->cancelling = 1; @@ -298,7 +309,7 @@ #if defined(_PTHREADS_INVARIANTS) if (THR_IN_CRITICAL(curthread)) - PANIC("thread exits with resources held!"); + PANIC("thread %p exits with resources held!", curthread); #endif /* * Kernel will do wakeup at the address, so joiner thread Index: lib/libthr/thread/thr_mutex.c =================================================================== --- lib/libthr/thread/thr_mutex.c +++ lib/libthr/thread/thr_mutex.c @@ -135,13 +135,9 @@ { #if defined(_PTHREADS_INVARIANTS) - if (__predict_false(m->m_qe.tqe_prev == NULL)) { - char msg[128]; - snprintf(msg, sizeof(msg), - "mutex %p own %#x is not on list %p %p", + if (__predict_false(m->m_qe.tqe_prev == NULL)) + PANIC("mutex %p own %#x is not on list %p %p", m, m->m_lock.m_owner, m->m_qe.tqe_prev, m->m_qe.tqe_next); - PANIC(msg); - } #endif } @@ -152,27 +148,20 @@ #if defined(_PTHREADS_INVARIANTS) if (__predict_false(m->m_qe.tqe_prev != NULL || - m->m_qe.tqe_next != NULL)) { - char msg[128]; - snprintf(msg, sizeof(msg), - "mutex %p own %#x is on list %p %p", + m->m_qe.tqe_next != NULL)) + PANIC("mutex %p own %#x is on list %p %p", m, m->m_lock.m_owner, m->m_qe.tqe_prev, m->m_qe.tqe_next); - PANIC(msg); - } if (__predict_false(is_robust_mutex(m) && (m->m_lock.m_rb_lnk != 0 || m->m_rb_prev != NULL || (is_pshared_mutex(m) && curthread->robust_list == (uintptr_t)&m->m_lock) || (!is_pshared_mutex(m) && curthread->priv_robust_list == - (uintptr_t)&m->m_lock)))) { - char msg[128]; - snprintf(msg, sizeof(msg), + (uintptr_t)&m->m_lock)))) + PANIC( "mutex %p own %#x is on robust linkage %p %p head %p phead %p", m, m->m_lock.m_owner, (void *)m->m_lock.m_rb_lnk, m->m_rb_prev, (void *)curthread->robust_list, (void *)curthread->priv_robust_list); - PANIC(msg); - } #endif } Index: lib/libthr/thread/thr_printf.c =================================================================== --- lib/libthr/thread/thr_printf.c +++ lib/libthr/thread/thr_printf.c @@ -52,23 +52,35 @@ void _thread_printf(int fd, const char *fmt, ...) { + va_list ap; + + va_start(ap, fmt); + _thread_vprintf(fd, fmt, ap); + va_end(ap); +} + +void +_thread_vprintf(int fd, const char *fmt, va_list ap) +{ static const char digits[16] = "0123456789abcdef"; - va_list ap; char buf[20]; char *s; unsigned long r, u; int c; long d; - int islong; + int islong, isalt; - va_start(ap, fmt); while ((c = *fmt++)) { + isalt = 0; islong = 0; if (c == '%') { next: c = *fmt++; if (c == '\0') - goto out; + return; switch (c) { + case '#': + isalt = 1; + goto next; case 'c': pchar(fd, va_arg(ap, int)); continue; @@ -79,10 +91,13 @@ islong = 1; goto next; case 'p': + pstr(fd, "0x"); islong = 1; case 'd': case 'u': case 'x': + if (c == 'x' && isalt) + pstr(fd, "0x"); r = ((c == 'u') || (c == 'd')) ? 10 : 16; if (c == 'd') { if (islong) @@ -111,8 +126,6 @@ } pchar(fd, c); } -out: - va_end(ap); } /* Index: lib/libthr/thread/thr_private.h =================================================================== --- lib/libthr/thread/thr_private.h +++ lib/libthr/thread/thr_private.h @@ -86,7 +86,7 @@ /* * Kernel fatal error handler macro. */ -#define PANIC(string) _thread_exit(__FILE__,__LINE__,string) +#define PANIC(args...) _thread_exitf(__FILE__, __LINE__, ##args) /* Output debug messages like this: */ #define stdout_debug(args...) _thread_printf(STDOUT_FILENO, ##args) @@ -780,6 +780,8 @@ void _libpthread_init(struct pthread *) __hidden; struct pthread *_thr_alloc(struct pthread *) __hidden; void _thread_exit(const char *, int, const char *) __hidden __dead2; +void _thread_exitf(const char *, int, const char *, ...) __hidden __dead2 + __printflike(3, 4); int _thr_ref_add(struct pthread *, struct pthread *, int) __hidden; void _thr_ref_delete(struct pthread *, struct pthread *) __hidden; void _thr_ref_delete_unlocked(struct pthread *, struct pthread *) __hidden; @@ -791,7 +793,8 @@ void _thr_free(struct pthread *, struct pthread *) __hidden; void _thr_gc(struct pthread *) __hidden; void _thread_cleanupspecific(void) __hidden; -void _thread_printf(int, const char *, ...) __hidden; +void _thread_printf(int, const char *, ...) __hidden __printflike(2, 3); +void _thread_vprintf(int, const char *, va_list) __hidden; void _thr_spinlock_init(void) __hidden; void _thr_cancel_enter(struct pthread *) __hidden; void _thr_cancel_enter2(struct pthread *, int) __hidden;