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) --------------------------- Use http://oss.sgi.com/ecartis to modify your settings or to unsubscribe.