aboutsummaryrefslogtreecommitdiff
path: root/sys/ddb/db_thread.c
diff options
context:
space:
mode:
authorJohn Baldwin <jhb@FreeBSD.org>2006-04-25 20:22:48 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2006-04-25 20:22:48 +0000
commitd605beaaa8ed9a27a640c51547f1c776347a0d66 (patch)
tree5fe039d6c6b0a45e1f891fbf1c32071b18e1ca50 /sys/ddb/db_thread.c
parent7edf55d7ff04cc7fc59b3933c266e7109e208cbb (diff)
downloadsrc-d605beaaa8ed9a27a640c51547f1c776347a0d66.tar.gz
src-d605beaaa8ed9a27a640c51547f1c776347a0d66.zip
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.
Notes
Notes: svn path=/head/; revision=158029
Diffstat (limited to 'sys/ddb/db_thread.c')
-rw-r--r--sys/ddb/db_thread.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/sys/ddb/db_thread.c b/sys/ddb/db_thread.c
index 5b50f5657d92..a946dd81f3df 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);
+}