summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjhb <jhb@FreeBSD.org>2002-09-19 18:46:29 +0000
committerjhb <jhb@FreeBSD.org>2002-09-19 18:46:29 +0000
commit03dc7bc4a4835049f8702ae7cd0097de1673c8f5 (patch)
treec1476f925d34a2b15d6347328a15e33a91997d2f
parent862a7a02065e4deed0e9939de05e07f75b74325c (diff)
downloadFreeBSD-src-03dc7bc4a4835049f8702ae7cd0097de1673c8f5.zip
FreeBSD-src-03dc7bc4a4835049f8702ae7cd0097de1673c8f5.tar.gz
Implement db_print_backtrace() if DDB is compiled into the kernel. This
MD function is just a wrapper around db_stack_trace_cmd() that prints out a backtrace of curthread. Currently, this function is only implemented on i386 and alpha (and the alpha version isn't quite tested yet, will do that in a bit). Other changes: - For i386, fix a bug in the raw frame address case. The eip we extract from the passed in frame address does not match the frame we received. Thus, instead of printing a bogus frame with the wrong eip, go ahead and advance frame down to the same frame as the eip we are using. - For alpha, attempt to add a way of doing a raw trace for alpha. Instead of passing a frame address in 'addr', pass in a pointer to a structure containing PC and KSP and use those to start the backtrace. The alpha db_print_backtrace() uses asm to read in the current PC and KSP values into such a request. Tested on: i386 Requested by: many
-rw-r--r--sys/alpha/alpha/db_trace.c27
-rw-r--r--sys/amd64/amd64/db_trace.c9
-rw-r--r--sys/ddb/ddb.h3
-rw-r--r--sys/i386/i386/db_trace.c9
-rw-r--r--sys/ia64/ia64/db_trace.c5
-rw-r--r--sys/powerpc/powerpc/db_trace.c4
-rw-r--r--sys/sparc64/sparc64/db_trace.c5
7 files changed, 60 insertions, 2 deletions
diff --git a/sys/alpha/alpha/db_trace.c b/sys/alpha/alpha/db_trace.c
index f84d1b9..b8a200c 100644
--- a/sys/alpha/alpha/db_trace.c
+++ b/sys/alpha/alpha/db_trace.c
@@ -60,6 +60,11 @@
#include <ddb/db_output.h>
#include <alpha/alpha/db_instruction.h>
+struct trace_request {
+ register_t ksp;
+ register_t pc;
+};
+
/*
* Information about the `standard' Alpha function prologue.
*/
@@ -260,8 +265,16 @@ db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, char *m
frame = addr;
}
} else {
- db_printf("alpha trace requires known PC =eject=\n");
- return;
+ struct trace_request *tr;
+
+ tr = (struct trace_request *)addr;
+ if (tr->ksp >= KERNBASE && tr->pc >= KERNBASE) {
+ db_printf("alpha trace requires known PC =eject=\n");
+ return;
+ }
+ callpc = tr->pc;
+ addr = tr->ksp;
+ frame = addr;
}
while (count--) {
@@ -377,7 +390,17 @@ db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, char *m
}
}
+void
+db_stack_trace_cmd(void)
+{
+ struct trace_request tr;
+ __asm __volatile(
+ " stq sp,%0 \n"
+ " stq pc,%1 \n"
+ : "=r" (tr.ksp), "=r" (tr.pc));
+ db_stack_trace_cmd(&tr, 1, -1, NULL);
+}
int
db_md_set_watchpoint(addr, size)
diff --git a/sys/amd64/amd64/db_trace.c b/sys/amd64/amd64/db_trace.c
index 8ac4c01..f3688c5 100644
--- a/sys/amd64/amd64/db_trace.c
+++ b/sys/amd64/amd64/db_trace.c
@@ -350,6 +350,7 @@ db_stack_trace_cmd(addr, have_addr, count, modif)
p = NULL;
frame = (struct i386_frame *)addr;
callpc = (db_addr_t)db_get_value((int)&frame->f_retaddr, 4, FALSE);
+ frame = frame->f_frame;
}
first = TRUE;
@@ -470,6 +471,14 @@ DB_DRX_FUNC(dr6)
DB_DRX_FUNC(dr7)
+void
+db_print_backtrace(void)
+{
+ register_t ebp;
+
+ __asm __volatile("mov %%ebp,%0\n" : "=r" (ebp));
+ db_stack_trace_cmd(ebp, 1, -1, NULL);
+}
int
i386_set_watch(watchnum, watchaddr, size, access, d)
diff --git a/sys/ddb/ddb.h b/sys/ddb/ddb.h
index ce3ffc4..1eb87ba 100644
--- a/sys/ddb/ddb.h
+++ b/sys/ddb/ddb.h
@@ -134,6 +134,9 @@ db_cmdfcn_t ipc_port_print;
db_cmdfcn_t vm_page_print;
#endif
+/* Scare the user with backtrace of curthread to console. */
+void db_print_backtrace(void);
+
/*
* Command table.
*/
diff --git a/sys/i386/i386/db_trace.c b/sys/i386/i386/db_trace.c
index 8ac4c01..f3688c5 100644
--- a/sys/i386/i386/db_trace.c
+++ b/sys/i386/i386/db_trace.c
@@ -350,6 +350,7 @@ db_stack_trace_cmd(addr, have_addr, count, modif)
p = NULL;
frame = (struct i386_frame *)addr;
callpc = (db_addr_t)db_get_value((int)&frame->f_retaddr, 4, FALSE);
+ frame = frame->f_frame;
}
first = TRUE;
@@ -470,6 +471,14 @@ DB_DRX_FUNC(dr6)
DB_DRX_FUNC(dr7)
+void
+db_print_backtrace(void)
+{
+ register_t ebp;
+
+ __asm __volatile("mov %%ebp,%0\n" : "=r" (ebp));
+ db_stack_trace_cmd(ebp, 1, -1, NULL);
+}
int
i386_set_watch(watchnum, watchaddr, size, access, d)
diff --git a/sys/ia64/ia64/db_trace.c b/sys/ia64/ia64/db_trace.c
index ffd8302..df630b2 100644
--- a/sys/ia64/ia64/db_trace.c
+++ b/sys/ia64/ia64/db_trace.c
@@ -134,6 +134,11 @@ db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count, char *m
ia64_free_unwind_state(us);
}
+void
+db_print_backtrace(void)
+{
+}
+
int
db_md_set_watchpoint(addr, size)
db_expr_t addr;
diff --git a/sys/powerpc/powerpc/db_trace.c b/sys/powerpc/powerpc/db_trace.c
index fe5efce..0ea9758 100644
--- a/sys/powerpc/powerpc/db_trace.c
+++ b/sys/powerpc/powerpc/db_trace.c
@@ -291,3 +291,7 @@ db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count,
db_stack_trace_print(addr, have_addr, count, modif, db_printf);
}
+void
+db_print_backtrace(void)
+{
+}
diff --git a/sys/sparc64/sparc64/db_trace.c b/sys/sparc64/sparc64/db_trace.c
index 417cb80..92f7ccb 100644
--- a/sys/sparc64/sparc64/db_trace.c
+++ b/sys/sparc64/sparc64/db_trace.c
@@ -305,3 +305,8 @@ db_utrace(struct thread *td, struct trapframe *tf)
}
db_printf("done\n");
}
+
+void
+db_stack_trace_cmd(void)
+{
+}
OpenPOWER on IntegriCloud