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.

Reply via email to