Add two helper functions: db_lookup_thread() and db_lookup_proc(). They

take the addr value passed to a ddb command and attempt to use it to
lookup a struct thread * or struct proc *, respectively.  Each function
first reparses the passed in value as if it was an ID entered in base 10.
For threads the ID is treated as a thread ID, for proceses the ID is
treated as a PID.  If a thread or proc matching the ID is found, it is
returned.  For db_lookup_thread(), if the check_pid argument is true and
it didn't find a thread with a matching thread ID, it will treat the ID as
a PID and look for a matching process.  If it finds one it returns the
first thread in the process.  If none of the ID lookups succeeded, then
the functions assume that the passed in address is a thread or proc
pointer, respectively.  This allows one to use tids, pids, or structure
pointers interchangeably in ddb functions that want to lookup threads or
processes if desired.
This commit is contained in:
John Baldwin 2006-04-25 20:22:48 +00:00
parent 7edf55d7ff
commit d605beaaa8
2 changed files with 94 additions and 0 deletions

View File

@ -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);
}

View File

@ -101,6 +101,8 @@ void db_error(const char *s);
int db_expression(db_expr_t *valuep);
int db_get_variable(db_expr_t *valuep);
void db_iprintf(const char *,...) __printflike(1, 2);
struct proc *db_lookup_proc(db_expr_t addr);
struct thread *db_lookup_thread(db_expr_t addr, boolean_t check_pid);
struct vm_map *db_map_addr(vm_offset_t);
boolean_t db_map_current(struct vm_map *);
boolean_t db_map_equal(struct vm_map *, struct vm_map *);