[PATCH] fix KDB backtrace for ppc64
Ananth N Mavinakayanahalli
ananth at in.ibm.com
Tue May 11 21:13:23 EST 2004
On Fri, May 07, 2004 at 05:15:32PM +1000, Anton Blanchard wrote:
Hi Anton,
>
> > Here is a patch that fixes backtracing in KDB for ppc64. We were not
> > handling the link register and were missing an intermediate call
> > during bt.
>
> Have you seen Pauls changes to arch/ppc64/kernel/process.c:show_stack in
> ameslab-2.5? It uses a trick to find exception frames and dump them
> correctly. I think it would be good to get the same magic into kdb.
Here is Paul's show_stack() retrofitted to be used with kdb's arch
specific backtrace.
This patch applies on my earlier reworked backtrace patch.
Here is a sample trace:
kdb> g
Instruction(i) breakpoint #0 at 0xc00000000004cc9c (adjusted)
0xc00000000004cc9c .__do_softirq trap
Entering kdb (current=0xc00000003d323690, pid 652) due to Breakpoint @ 0xc00000c
kdb> bt
Stack traceback for pid 652
0xc00000003d323690 652 1 1 0 R 0xc00000003d323af8 *master
SP(esp) PC(eip) Function(args)
0xc00000003d31f3e0 0xc00000000004cc9c .__do_softirq +0x0
0xc00000003d31f3e0 0xc00000000004ce44 (lr) .do_softirq +0x6c
0xc00000003d31f460 0xc000000000013fac .timer_interrupt +0x2a0
0xc00000003d31f540 0xc00000000000a2c0 Decrementer_common +0xe8
--- Exception: 900: (Decrementer) at .__d_lookup +0x8c
0xc00000003d31f830 0xc0000000000a22cc .__d_lookup +0x8c
0xc00000003d31f830 0xc00000000009643c (lr) .do_lookup +0x48
0xc00000003d31f900 0xc00000000009643c .do_lookup +0x48
0xc00000003d31f9b0 0xc0000000000986a4 .link_path_walk +0x654
0xc00000003d31fa70 0xc0000000000991f4 .path_lookup +0xc0
0xc00000003d31faf0 0xc0000000000993bc .open_namei +0xc0
0xc00000003d31fbc0 0xc000000000083324 .filp_open +0x38
0xc00000003d31fc70 0xc00000000001d670 .sys32_open +0x90
0xc00000003d31fd10 0xc00000000000fe8c .ret_from_syscall_1 +0x0
--- Exception: c00: (System Call) NO_SYMBOL or Userspace
0x00000000ffffe8c0 0x000000000fbf8208
<Stack contents outside of kernel space. 00000000ffffe8c0>
kdb>
Thanks,
Ananth
--
Ananth Narayan
Linux Technology Center,
IBM Software Lab, INDIA
diff -Naur --exclude=BitKeeper --exclude=SCCS temp/ameslab/arch/ppc64/kdb/kdba_bt.c ameslab/arch/ppc64/kdb/kdba_bt.c
--- temp/ameslab/arch/ppc64/kdb/kdba_bt.c 2004-05-11 02:19:27.576319008 -0700
+++ ameslab/arch/ppc64/kdb/kdba_bt.c 2004-05-11 02:04:51.837327584 -0700
@@ -68,22 +68,8 @@
return ret;
}
-
extern unsigned long kdba_getword(unsigned long addr, size_t width);
-/* Copy a block of memory using kdba_getword().
- * This is not efficient.
- */
-static void kdba_getmem(unsigned long addr, void *p, int size)
-{
- unsigned char *dst = (unsigned char *)p;
- while (size > 0) {
- *dst++ = kdba_getword(addr++, 1);
- size--;
- }
-}
-
-
/*
* kdba_bt_stack_ppc
*
@@ -102,13 +88,12 @@
{
kdb_machreg_t esp, eip, ebp, old_esp;
- /* declare these as raw ptrs so we don't get func descriptors */
- extern void *ret_from_except, *ret_from_syscall_1;
const char *name;
unsigned long symsize, symoffset;
char *symmodname;
int flag = 0;
+ kdb_machreg_t lr;
char namebuf[128];
/*
@@ -207,7 +192,6 @@
}
kdb_printf("\n");
if (!flag && (task_curr(p))) {
- kdb_machreg_t lr;
unsigned long start = 0, end = 0;
flag++;
@@ -234,35 +218,36 @@
kdb_printf("<Stack contents outside of kernel space. %.16lx>\n", esp );
break;
} else {
- if (eip == (kdb_machreg_t)ret_from_except ||
- eip == (kdb_machreg_t)ret_from_syscall_1) {
- /* pull exception regs from the stack */
- struct pt_regs eregs;
- kdba_getmem(esp+STACK_FRAME_OVERHEAD,
- &eregs, sizeof(eregs));
- kdb_printf(" [exception: %lx:%s regs 0x%lx] "
- "nip:[0x%lx] gpr[1]:[0x%lx]\n",
- eregs.trap,getvecname(eregs.trap),
- esp+STACK_FRAME_OVERHEAD,
- (unsigned long int)eregs.nip,
- (unsigned long int)eregs.gpr[1]);
- old_esp = esp;
- esp = kdba_getword(esp, 8);
- if (!esp)
- break;
- eip = kdba_getword(esp+16, 8); /* saved lr */
- if (esp < PAGE_OFFSET) { /* userspace... */
- if (old_esp > PAGE_OFFSET) {
- kdb_printf("<Stack drops into userspace here %.16lx>\n",esp);
- break;
- }
- }
- /*
- * we want to follow exception registers,
- * not into user stack. ...
- */
- esp = eregs.gpr[1];
- eip = eregs.nip;
+ unsigned long *sp = (unsigned long *)esp;
+ if (esp <= (unsigned long) p->thread_info + THREAD_SIZE
+ + sizeof(struct pt_regs) + 400
+ && sp[12] == 0x7265677368657265) {
+ struct pt_regs *eregs = (struct pt_regs *)
+ (esp + STACK_FRAME_OVERHEAD);
+ kdb_printf("--- Exception: %lx: %s ",
+ eregs->trap, getvecname(eregs->trap));
+ name = kallsyms_lookup(eregs->nip, &symsize,
+ &symoffset, &symmodname, namebuf);
+ if (name) {
+ kdb_printf("at %s +0x%lx\n",
+ name, symoffset);
+ } else {
+ kdb_printf("NO_SYMBOL or Userspace\n");
+ }
+ flag = 0;
+ if (esp < PAGE_OFFSET) { /* userspace... */
+ if (old_esp > PAGE_OFFSET) {
+ kdb_printf("<Stack drops into userspace here %.16lx>\n",esp);
+ break;
+ }
+ }
+ /*
+ * we want to follow exception registers,
+ * not into user stack. ...
+ */
+ esp = eregs->gpr[1];
+ eip = eregs->nip;
+ regs = eregs;
} else {
esp = kdba_getword(esp, 8);
if (!esp)
** Sent via the linuxppc64-dev mail list. See http://lists.linuxppc.org/
More information about the Linuxppc64-dev
mailing list