summaryrefslogtreecommitdiffstats
path: root/sys/ddb
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2011-12-16 11:44:20 +0000
committerkib <kib@FreeBSD.org>2011-12-16 11:44:20 +0000
commit02726a0b7125ed1de732abb3b4a16c11c1f262dc (patch)
tree57c1c1ff080a1cf0b1ec9827042cb3de5bc318f0 /sys/ddb
parent30b0342f622275bfb4948b796470712830e2626a (diff)
downloadFreeBSD-src-02726a0b7125ed1de732abb3b4a16c11c1f262dc.zip
FreeBSD-src-02726a0b7125ed1de732abb3b4a16c11c1f262dc.tar.gz
Add 'findstack' ddb command to search either the thread kernel stack
or cached stack containing the specified kernel virtual address. Discussed with: pho MFC after: 1 week
Diffstat (limited to 'sys/ddb')
-rw-r--r--sys/ddb/db_command.c1
-rw-r--r--sys/ddb/db_ps.c37
-rw-r--r--sys/ddb/ddb.h1
3 files changed, 39 insertions, 0 deletions
diff --git a/sys/ddb/db_command.c b/sys/ddb/db_command.c
index f2e2c42..e0f14b9 100644
--- a/sys/ddb/db_command.c
+++ b/sys/ddb/db_command.c
@@ -140,6 +140,7 @@ static struct command db_cmds[] = {
{ "unscript", db_unscript_cmd, CS_OWN, 0 },
{ "capture", db_capture_cmd, CS_OWN, 0 },
{ "textdump", db_textdump_cmd, CS_OWN, 0 },
+ { "findstack", db_findstack_cmd, 0, 0 },
};
struct command_table db_cmd_table = LIST_HEAD_INITIALIZER(db_cmd_table);
diff --git a/sys/ddb/db_ps.c b/sys/ddb/db_ps.c
index 0c45183..fcd1bd0 100644
--- a/sys/ddb/db_ps.c
+++ b/sys/ddb/db_ps.c
@@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <sys/proc.h>
#include <sys/sysent.h>
#include <sys/systm.h>
+#include <sys/_kstack_cache.h>
#include <vm/vm.h>
#include <vm/vm_param.h>
#include <vm/pmap.h>
@@ -429,3 +430,39 @@ DB_SHOW_COMMAND(proc, db_show_proc)
break;
}
}
+
+void
+db_findstack_cmd(db_expr_t addr, boolean_t have_addr,
+ db_expr_t dummy3 __unused, char *dummy4 __unused)
+{
+ struct proc *p;
+ struct thread *td;
+ struct kstack_cache_entry *ks_ce;
+ vm_offset_t saddr;
+
+ if (have_addr)
+ saddr = addr;
+ else {
+ db_printf("Usage: findstack <address>\n");
+ return;
+ }
+
+ for (p = LIST_FIRST(&allproc); p != NULL; p = LIST_NEXT(p, p_list)) {
+ FOREACH_THREAD_IN_PROC(p, td) {
+ if (td->td_kstack <= saddr && saddr < td->td_kstack +
+ PAGE_SIZE * td->td_kstack_pages) {
+ db_printf("Thread %p\n", td);
+ return;
+ }
+ }
+ }
+
+ for (ks_ce = kstack_cache; ks_ce != NULL;
+ ks_ce = ks_ce->next_ks_entry) {
+ if ((vm_offset_t)ks_ce <= saddr && saddr < (vm_offset_t)ks_ce +
+ PAGE_SIZE * KSTACK_PAGES) {
+ db_printf("Cached stack %p\n", ks_ce);
+ return;
+ }
+ }
+}
diff --git a/sys/ddb/ddb.h b/sys/ddb/ddb.h
index 9b240b6..93bf713 100644
--- a/sys/ddb/ddb.h
+++ b/sys/ddb/ddb.h
@@ -226,6 +226,7 @@ db_cmdfcn_t db_delete_cmd;
db_cmdfcn_t db_deletehwatch_cmd;
db_cmdfcn_t db_deletewatch_cmd;
db_cmdfcn_t db_examine_cmd;
+db_cmdfcn_t db_findstack_cmd;
db_cmdfcn_t db_hwatchpoint_cmd;
db_cmdfcn_t db_listbreak_cmd;
db_cmdfcn_t db_scripts_cmd;
OpenPOWER on IntegriCloud