From 199183d5babe50b05ef4b91e2bba390fa2d4bf06 Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Sun, 22 Nov 2009 20:54:00 +0100 Subject: Show command lines in task list * Makefile.am (clib_routines): Add memcmp. * i386/i386/db_machdep.h (DB_GNUMACH_TASK_NAME): New macro. * i386/i386/db_interface.c (GNU): New macro. [GNU] (looks_like_command): New function. (db_task_name): When task map is kernel_pmap, return DB_GNUMACH_TASK_NAME. [GNU] (db_task_name): Use a GNU/Hurd-specific heuristic to get argv[] of a task. --- Makefile.am | 2 +- i386/i386/db_interface.c | 93 ++++++++++++++++++++++++++++++++++++++++++++++++ i386/i386/db_machdep.h | 1 + 3 files changed, 95 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index d6fbb54..25fd403 100644 --- a/Makefile.am +++ b/Makefile.am @@ -133,7 +133,7 @@ noinst_PROGRAMS += \ gnumach.o # This is the list of routines we decide is OK to steal from the C library. -clib_routines := memcpy memmove memset bcopy bzero \ +clib_routines := memcmp memcpy memmove memset bcopy bzero \ strchr strstr strsep strpbrk strtok \ htonl htons ntohl ntohs \ udivdi3 __udivdi3 \ diff --git a/i386/i386/db_interface.c b/i386/i386/db_interface.c index be0c893..d149adc 100644 --- a/i386/i386/db_interface.c +++ b/i386/i386/db_interface.c @@ -520,6 +520,53 @@ db_search_null( return FALSE; } +#define GNU + +#ifdef GNU +static boolean_t +looks_like_command( + task_t task, + char* kaddr) +{ + char *c; + + assert(!((vm_offset_t) kaddr & (INTEL_PGBYTES-1))); + + /* + * Must be the environment. + */ + if (!memcmp(kaddr, "PATH=", 5) || !memcmp(kaddr, "TERM=", 5) || !memcmp(kaddr, "SHELL=", 6) || !memcmp(kaddr, "LOCAL_PART=", 11) || !memcmp(kaddr, "LC_ALL=", 7)) + return FALSE; + + /* + * This is purely heuristical but works quite nicely. + * We know that it should look like words separated by \0, and + * eventually only \0s. + */ + c = kaddr; + while (c < kaddr + INTEL_PGBYTES) { + if (!*c) { + if (c == kaddr) + /* Starts by \0. */ + return FALSE; + break; + } + while (c < kaddr + INTEL_PGBYTES && *c) + c++; + if (c < kaddr + INTEL_PGBYTES) + c++; /* Skip \0 */ + } + /* + * Check that the remainder is just \0s. + */ + while (c < kaddr + INTEL_PGBYTES) + if (*c++) + return FALSE; + + return TRUE; +} +#endif + void db_task_name( task_t task) @@ -527,7 +574,46 @@ db_task_name( register char *p; register int n; unsigned vaddr, kaddr; + unsigned sp; + if (task->map->pmap == kernel_pmap) { + db_printf(DB_GNUMACH_TASK_NAME); + return; + } + +#ifdef GNU + /* + * GNU Hurd-specific heuristics. + */ + + /* Heuristical address first. */ + vaddr = 0x1026000; + if (db_user_to_kernel_address(task, vaddr, &kaddr, 0) >= 0 && + looks_like_command(task, (char*) kaddr)) + goto ok; + + /* Try to catch SP of the main thread. */ + thread_t thread; + + task_lock(task); + thread = (thread_t) queue_first(&task->thread_list); + if (!thread) { + task_unlock(task); + db_printf(DB_NULL_TASK_NAME); + return; + } + sp = thread->pcb->iss.uesp; + task_unlock(task); + + vaddr = (sp & ~(INTEL_PGBYTES - 1)) + INTEL_PGBYTES; + while (1) { + if (db_user_to_kernel_address(task, vaddr, &kaddr, 0) < 0) + return FALSE; + if (looks_like_command(task, (char*) kaddr)) + break; + vaddr += INTEL_PGBYTES; + } +#else vaddr = DB_USER_STACK_ADDR; kaddr = 0; @@ -545,11 +631,18 @@ db_task_name( db_printf(DB_NULL_TASK_NAME); return; } +#endif +ok: n = DB_TASK_NAME_LEN-1; +#ifdef GNU + p = (char *)kaddr; + for (; n > 0; vaddr++, p++, n--) { +#else p = (char *)kaddr + sizeof(unsigned); for (vaddr += sizeof(int); vaddr < DB_USER_STACK_ADDR && n > 0; vaddr++, p++, n--) { +#endif if (vaddr % INTEL_PGBYTES == 0) { (void)db_user_to_kernel_address(task, vaddr, &kaddr, 0); p = (char*)kaddr; diff --git a/i386/i386/db_machdep.h b/i386/i386/db_machdep.h index cba259c..95e3797 100644 --- a/i386/i386/db_machdep.h +++ b/i386/i386/db_machdep.h @@ -94,6 +94,7 @@ db_regs_t ddb_regs; /* register state */ #define DB_TASK_NAME_TITLE "COMMAND " #define DB_TASK_NAME_LEN 23 #define DB_NULL_TASK_NAME "? " +#define DB_GNUMACH_TASK_NAME "gnumach " /* macro for checking if a thread has used floating-point */ -- cgit v1.2.3