Module Name:    src
Committed By:   yamt
Date:           Thu Apr 14 16:05:59 UTC 2011

Modified Files:
        src/sys/arch/i386/i386: db_machdep.c

Log Message:
fix backtrace of interrupt


To generate a diff of this commit:
cvs rdiff -u -r1.2 -r1.3 src/sys/arch/i386/i386/db_machdep.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/i386/i386/db_machdep.c
diff -u src/sys/arch/i386/i386/db_machdep.c:1.2 src/sys/arch/i386/i386/db_machdep.c:1.3
--- src/sys/arch/i386/i386/db_machdep.c:1.2	Mon Apr 11 04:22:31 2011
+++ src/sys/arch/i386/i386/db_machdep.c	Thu Apr 14 16:05:59 2011
@@ -1,4 +1,4 @@
-/*	$NetBSD: db_machdep.c,v 1.2 2011/04/11 04:22:31 mrg Exp $	*/
+/*	$NetBSD: db_machdep.c,v 1.3 2011/04/14 16:05:59 yamt Exp $	*/
 
 /* 
  * Mach Operating System
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: db_machdep.c,v 1.2 2011/04/11 04:22:31 mrg Exp $");
+__KERNEL_RCSID(0, "$NetBSD: db_machdep.c,v 1.3 2011/04/14 16:05:59 yamt Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -217,8 +217,7 @@
 	static struct trapframe tf;
 	static struct i386tss tss;
 	struct i386_frame *fp;
-	struct intrframe *ifp;
-	int traptype, trapno, err, i;
+	int traptype;
 	uintptr_t ptr;
 
 	switch (is_trap) {
@@ -256,24 +255,23 @@
 	    case INTERRUPT:
 	    default:
 		/* The only argument to trap() or syscall() is the trapframe. */
-		ptr = db_get_value((int)argp, 4, false);
-		db_read_bytes((db_addr_t)ptr, sizeof(tf), (char *)&tf);
 		switch (is_trap) {
 		case TRAP:
+			ptr = db_get_value((int)argp, 4, false);
+			db_read_bytes((db_addr_t)ptr, sizeof(tf), (char *)&tf);
 			(*pr)("--- trap (number %d) ---\n", tf.tf_trapno);
 			break;
 		case SYSCALL:
+			ptr = db_get_value((int)argp, 4, false);
+			db_read_bytes((db_addr_t)ptr, sizeof(tf), (char *)&tf);
 			(*pr)("--- syscall (number %d) ---\n", tf.tf_eax);
 			break;
 		case INTERRUPT:
 			(*pr)("--- interrupt ---\n");
 			/*
-			 * Get intrframe address as saved when switching
-			 * to interrupt stack, and convert to trapframe
-			 * (add 4).  See frame.h.
+			 * see the "XXX -1 here is a hack" comment below.
 			 */
-			ptr = db_get_value((int)(argp - 1) + 4, 4, false);
-			db_read_bytes((db_addr_t)ptr, sizeof(tf), (char *)&tf);
+			db_read_bytes((db_addr_t)argp, sizeof(tf), (char *)&tf);
 			break;
 		}
 		*ip = (db_addr_t)tf.tf_eip;
@@ -295,16 +293,32 @@
 	if (db_frame_info(*nextframe, (db_addr_t)*ip, NULL, NULL, &traptype,
 	    NULL) != (db_sym_t)0
 	    && traptype == INTERRUPT) {
-		for (i = 0; i < 4; i++) {
-			ifp = (struct intrframe *)(argp + i);
-			err = db_get_value((int)&ifp->__if_err, 4, false);
-			trapno = db_get_value((int)&ifp->__if_trapno, 4, false);
-			if ((err == 0 || err == IREENT_MAGIC) && trapno == T_ASTFLT) {
-				*nextframe = (long *)ifp - 1;
-				break;
-			}
-		}
-		if (i == 4) {
+		struct intrframe *ifp;
+		int trapno;
+		int err;
+
+		/*
+		 * 2nd argument of interrupt handlers is a pointer to intrframe.
+		 */
+		ifp = (struct intrframe *)
+		    db_get_value((db_addr_t)(argp + 1), sizeof(ifp), false);
+		/*
+		 * check if it's a valid intrframe.
+		 */
+		err = db_get_value((db_addr_t)&ifp->__if_err,
+		    sizeof(ifp->__if_err), false);
+		trapno = db_get_value((db_addr_t)&ifp->__if_trapno,
+		    sizeof(ifp->__if_trapno), false);
+		if ((err == 0 || err == IREENT_MAGIC) && trapno == T_ASTFLT) {
+			/*
+			 * found seemingly valid intrframe.
+			 *
+			 * XXX -1 here is a hack.
+			 * for the next frame, we will be called with
+			 * argp = *nextframe + 2.  (long *)if - 1 + 2 = &tf.
+			 */
+			*nextframe = (long *)ifp - 1;
+		} else {
 			(*pr)("DDB lost frame for ");
 			db_printsym(*ip, DB_STGY_ANY, pr);
 			(*pr)(", trying %p\n",argp);

Reply via email to