Module Name: src
Committed By: uwe
Date: Tue Aug 6 21:41:01 UTC 2013
Modified Files:
src/sys/arch/sh3/sh3: db_trace.c
Log Message:
db_stack_trace_print: support trace/[at], starting trace from switchframe.
To generate a diff of this commit:
cvs rdiff -u -r1.23 -r1.24 src/sys/arch/sh3/sh3/db_trace.c
Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.
Modified files:
Index: src/sys/arch/sh3/sh3/db_trace.c
diff -u src/sys/arch/sh3/sh3/db_trace.c:1.23 src/sys/arch/sh3/sh3/db_trace.c:1.24
--- src/sys/arch/sh3/sh3/db_trace.c:1.23 Sun Jun 8 22:02:08 2008
+++ src/sys/arch/sh3/sh3/db_trace.c Tue Aug 6 21:41:01 2013
@@ -1,4 +1,4 @@
-/* $NetBSD: db_trace.c,v 1.23 2008/06/08 22:02:08 uwe Exp $ */
+/* $NetBSD: db_trace.c,v 1.24 2013/08/06 21:41:01 uwe Exp $ */
/*-
* Copyright (c) 2000 Tsubai Masanari. All rights reserved.
@@ -27,7 +27,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: db_trace.c,v 1.23 2008/06/08 22:02:08 uwe Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_trace.c,v 1.24 2013/08/06 21:41:01 uwe Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -82,17 +82,76 @@ db_stack_trace_print(db_expr_t addr, boo
struct trapframe *tf;
db_addr_t callpc, frame, lastframe;
uint32_t vbr;
+ bool kernel_only = true;
+ bool lwpid = false;
+ bool lwpaddr = false;
+ const char *cp;
+ char c;
__asm volatile("stc vbr, %0" : "=r"(vbr));
- tf = &ddb_regs;
+ cp = modif;
+ while ((c = *cp++) != 0) {
+ if (c == 'a')
+ lwpaddr = true;
+ else if (c == 't')
+ lwpid = true;
+ else if (c == 'u')
+ kernel_only = false;
+ }
- frame = tf->tf_r14;
- callpc = tf->tf_spc;
+ if (lwpaddr && lwpid) {
+ db_printf("only one of /a or /t can be specified\n");
+ return;
+ }
+ if ((lwpaddr || lwpid) && !have_addr) {
+ db_printf("%s required\n", lwpaddr ? "address" : "pid");
+ return;
+ }
- if (callpc == 0) {
- (*print)("calling through null pointer?\n");
- callpc = tf->tf_pr;
+
+ if (!have_addr) {
+ tf = &ddb_regs;
+ frame = tf->tf_r14;
+ callpc = tf->tf_spc;
+ if (callpc == 0) {
+ (*print)("calling through null pointer?\n");
+ callpc = tf->tf_pr;
+ }
+ }
+ else if (lwpaddr || lwpid) {
+ struct proc *p;
+ struct lwp *l;
+ struct pcb *pcb;
+
+ if (lwpaddr) {
+ l = (struct lwp *)addr;
+ p = l->l_proc;
+ (*print)("trace: lwp addr %p pid %d ",
+ (void *)addr, p->p_pid);
+ }
+ else {
+ pid_t pid = (pid_t)addr;
+ (*print)("trace: pid %d ", pid);
+ p = proc_find_raw(pid);
+ if (p == NULL) {
+ (*print)("not found\n");
+ return;
+ }
+ l = LIST_FIRST(&p->p_lwps);
+ }
+ KASSERT(l != NULL);
+ (*print)("lid %d ", l->l_lid);
+ pcb = lwp_getpcb(l);
+ tf = (struct trapframe *)pcb->pcb_sf.sf_r6_bank;
+ frame = pcb->pcb_sf.sf_r14;
+ callpc = pcb->pcb_sf.sf_pr;
+ (*print)("at %p\n", frame);
+ }
+ else {
+ /* XXX */
+ db_printf("trace by frame address is not supported\n");
+ return;
}
lastframe = 0;