[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