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;