diff options
Diffstat (limited to 'sys/ddb/db_thread.c')
-rw-r--r-- | sys/ddb/db_thread.c | 92 |
1 files changed, 92 insertions, 0 deletions
diff --git a/sys/ddb/db_thread.c b/sys/ddb/db_thread.c index 5b50f56..a946dd8 100644 --- a/sys/ddb/db_thread.c +++ b/sys/ddb/db_thread.c @@ -38,6 +38,8 @@ __FBSDID("$FreeBSD$"); #include <ddb/db_command.h> #include <ddb/db_sym.h> +static db_expr_t hex2dec(db_expr_t expr); + void db_print_thread(void) { @@ -108,3 +110,93 @@ db_show_threads(db_expr_t addr, boolean_t hasaddr, db_expr_t cnt, char *mod) thr = kdb_thr_next(thr); } } + +/* + * Take the parsed expression value from the command line that was parsed + * as a hexadecimal value and convert it as if the expression was parsed + * as a decimal value. Returns -1 if the expression was not a valid + * decimal value. + */ +static db_expr_t +hex2dec(db_expr_t expr) +{ + uintptr_t x, y; + db_expr_t val; + + y = 1; + val = 0; + x = expr; + while (x != 0) { + if (x % 16 > 9) + return (-1); + val += (x % 16) * (y); + x >>= 4; + y *= 10; + } + return (val); +} + +/* + * Lookup a thread based on a db expression address. We assume that the + * address was parsed in hexadecimal. We reparse the address in decimal + * first and try to treat it as a thread ID to find an associated thread. + * If that fails and check_pid is true, we terat the decimal value as a + * PID. If that matches a process, we return the first thread in that + * process. Otherwise, we treat the addr as a pointer to a thread. + */ +struct thread * +db_lookup_thread(db_expr_t addr, boolean_t check_pid) +{ + struct thread *td; + db_expr_t decaddr; + struct proc *p; + + /* + * If the parsed address was not a valid decimal expression, + * assume it is a thread pointer. + */ + decaddr = hex2dec(addr); + if (decaddr == -1) + return ((struct thread *)addr); + + td = kdb_thr_lookup(decaddr); + if (td != NULL) + return (td); + if (check_pid) { + LIST_FOREACH(p, &allproc, p_list) { + if (p->p_pid == decaddr) + return (FIRST_THREAD_IN_PROC(p)); + } + LIST_FOREACH(p, &zombproc, p_list) { + if (p->p_pid == decaddr) + return (FIRST_THREAD_IN_PROC(p)); + } + } + return ((struct thread *)addr); +} + +/* + * Lookup a process based on a db expression address. We assume that the + * address was parsed in hexadecimal. We reparse the address in decimal + * first and try to treat it as a PID to find an associated process. + * If that fails we treat the addr as a pointer to a process. + */ +struct proc * +db_lookup_proc(db_expr_t addr) +{ + db_expr_t decaddr; + struct proc *p; + + decaddr = hex2dec(addr); + if (decaddr != -1) { + LIST_FOREACH(p, &allproc, p_list) { + if (p->p_pid == decaddr) + return (p); + } + LIST_FOREACH(p, &zombproc, p_list) { + if (p->p_pid == decaddr) + return (p); + } + } + return ((struct proc *)addr); +} |