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);
/*