diff --git a/include/mach/debug.defs b/include/mach/debug.defs new file mode 100644 index 0000000..49959ba --- /dev/null +++ b/include/mach/debug.defs @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2014 Free Software Foundation. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _KERN_DEBUG_DEFS_ +#define _KERN_DEBUG_DEFS_ + +type kernel_debug_name_t = c_string[*: 64]; + +#endif /* _KERN_DEBUG_DEFS_ */ diff --git a/include/mach/debug.h b/include/mach/debug.h new file mode 100644 index 0000000..149d800 --- /dev/null +++ b/include/mach/debug.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2014 Free Software Foundation. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _KERN_DEBUG_H_ +#define _KERN_DEBUG_H_ + +/* + * A fixed-length string data type intended for names given to + * kernel objects. + * + * Note that it is not guaranteed that the in-kernel data + * structure will hold KERNEL_DEBUG_NAME_MAX bytes. The given + * name will be truncated to fit into the target data structure. + */ +#define KERNEL_DEBUG_NAME_MAX (64) +typedef char kernel_debug_name_t[KERNEL_DEBUG_NAME_MAX]; + +#endif /* _KERN_DEBUG_H_ */ diff --git a/include/mach/gnumach.defs b/include/mach/gnumach.defs index 12c4e99..273e30b 100644 --- a/include/mach/gnumach.defs +++ b/include/mach/gnumach.defs @@ -27,6 +27,7 @@ subsystem #include #include +#include type vm_cache_statistics_data_t = struct[11] of integer_t; @@ -63,3 +64,11 @@ simpleroutine thread_terminate_release( reply_port : mach_port_name_t; address : vm_address_t; size : vm_size_t); + +/* + * Set the name of task TASK to NAME. This is a debugging aid. + * NAME will be used in error messages printed by the kernel. + */ +simpleroutine task_set_name( + task : task_t; + name : kernel_debug_name_t); diff --git a/ipc/mach_port.c b/ipc/mach_port.c index fbc5e69..891d2f2 100644 --- a/ipc/mach_port.c +++ b/ipc/mach_port.c @@ -571,7 +571,7 @@ mach_port_destroy( kr = ipc_right_lookup_write(space, name, &entry); if (kr != KERN_SUCCESS) { if (name != MACH_PORT_NULL && name != MACH_PORT_DEAD && space == current_space()) { - printf("task %p destroying an invalid port %lu, most probably a bug.\n", current_task(), name); + printf("task %.*s destroying an invalid port %lu, most probably a bug.\n", TASK_NAME_SIZE, current_task()->name, name); if (mach_port_deallocate_debug) SoftDebugger("mach_port_deallocate"); } @@ -615,7 +615,7 @@ mach_port_deallocate( kr = ipc_right_lookup_write(space, name, &entry); if (kr != KERN_SUCCESS) { if (name != MACH_PORT_NULL && name != MACH_PORT_DEAD && space == current_space()) { - printf("task %p deallocating an invalid port %lu, most probably a bug.\n", current_task(), name); + printf("task %.*s deallocating an invalid port %lu, most probably a bug.\n", TASK_NAME_SIZE, current_task()->name, name); if (mach_port_deallocate_debug) SoftDebugger("mach_port_deallocate"); } diff --git a/kern/printf.c b/kern/printf.c index af59d5a..ea78d48 100644 --- a/kern/printf.c +++ b/kern/printf.c @@ -615,6 +615,16 @@ vsnprintf(char *buf, size_t size, const char *fmt, va_list args) return cookie.index; } +int +snprintf(char *buf, size_t size, const char *fmt, ...) +{ + int written; + va_list listp; + va_start(listp, fmt); + written = vsnprintf(buf, size, fmt, listp); + va_end(listp); + return written; +} void safe_gets(str, maxlen) char *str; diff --git a/kern/printf.h b/kern/printf.h index 8b4e760..0f8b328 100644 --- a/kern/printf.h +++ b/kern/printf.h @@ -40,6 +40,7 @@ extern void printnum (unsigned long u, int base, vm_offset_t putc_arg); extern int sprintf (char *buf, const char *fmt, ...); +extern int snprintf (char *buf, size_t size, const char *fmt, ...); extern int vsnprintf (char *buf, size_t size, const char *fmt, va_list args); extern int printf (const char *fmt, ...); diff --git a/kern/slab.c b/kern/slab.c index d1e3632..3fc95b6 100644 --- a/kern/slab.c +++ b/kern/slab.c @@ -662,7 +662,8 @@ static void kmem_cache_error(struct kmem_cache *cache, void *buf, int error, { struct kmem_buftag *buftag; - kmem_error("cache: %s, buffer: %p", cache->name, (void *)buf); + kmem_error("cache: %.*s, buffer: %p", KMEM_CACHE_NAME_SIZE, cache->name, + (void *)buf); switch(error) { case KMEM_ERR_INVALID: diff --git a/kern/task.c b/kern/task.c index 13b3c76..0c45d43 100644 --- a/kern/task.c +++ b/kern/task.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include #include @@ -45,6 +46,7 @@ #include #include #include +#include #include /* for thread_wakeup */ #include #include @@ -164,6 +166,8 @@ kern_return_t task_create( } #endif /* FAST_TAS */ + snprintf (new_task->name, TASK_NAME_SIZE, "%p", new_task); + ipc_task_enable(new_task); *child_task = new_task; @@ -1068,6 +1072,21 @@ task_priority( } /* + * task_set_name + * + * Set the name of task TASK to NAME. This is a debugging aid. + * NAME will be used in error messages printed by the kernel. + */ +kern_return_t +task_set_name( + task_t task, + kernel_debug_name_t name) +{ + strncpy(task->name, name, sizeof task->name); + return KERN_SUCCESS; +} + +/* * task_collect_scan: * * Attempt to free resources owned by tasks. diff --git a/kern/task.h b/kern/task.h index e852033..bf5bb53 100644 --- a/kern/task.h +++ b/kern/task.h @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -48,6 +49,13 @@ #include #include +/* + * Task name buffer size. The size is chosen so that struct task fits + * into three cache lines. The size of a cache line on a typical CPU + * is 64 bytes. + */ +#define TASK_NAME_SIZE 32 + struct task { /* Synchronization/destruction information */ decl_simple_lock_data(,lock) /* Task's lock */ @@ -113,6 +121,8 @@ struct task { natural_t cow_faults; /* copy-on-write faults counter */ natural_t messages_sent; /* messages sent counter */ natural_t messages_received; /* messages received counter */ + + char name[TASK_NAME_SIZE]; }; #define task_lock(task) simple_lock(&(task)->lock) @@ -160,6 +170,9 @@ extern kern_return_t task_assign( extern kern_return_t task_assign_default( task_t task, boolean_t assign_threads); +extern kern_return_t task_set_name( + task_t task, + kernel_debug_name_t name); extern void consider_task_collect(void); /*