[issue1614] x86_64 garbled backtrace

YONETANI Tomokazu qhwt+dfly at les.ath.cx
Wed Nov 25 09:14:19 PST 2009


On Tue, Nov 24, 2009 at 09:01:54AM +0000, Alex Hornung (via DragonFly issue tracker) wrote:
> We really need to fix the garbled output of the db> trace on x86_64, it makes it 
> difficult to debug a number of issues.
> Does anyone have any insight on why this happens?

I've just committed an essential fix to this problem.  At least you have
functions list now.  However, calling print_backtrace() from kernel code
still triggers a GPF; I think this is probably because of missing INKERNEL()
-conditionals used here and there in i386 version.  I'm thinking of
applying something like this: (the last few lines in db_stack_trace_cmd()
are not brought in from i386 version, because doing so corrupts the
functions list in a different way than it used to do).

Cheers.

diff --git a/sys/platform/pc64/x86_64/db_trace.c b/sys/platform/pc64/x86_64/db_trace.c
index ec09e5f..8ddca3d 100644
--- a/sys/platform/pc64/x86_64/db_trace.c
+++ b/sys/platform/pc64/x86_64/db_trace.c
@@ -269,46 +269,37 @@ db_nextframe(struct x86_64_frame **fp, db_addr_t *ip)
 	 */
 	tf = (struct trapframe *)((long)*fp + 16);
 
+	if (INKERNEL(tf)) {
 #if 0
-	rsp = (ISPL(tf->tf_cs) == SEL_UPL) ?  tf->tf_rsp : (long)&tf->tf_rsp;
+		rsp = (ISPL(tf->tf_cs) == SEL_UPL) ?  tf->tf_rsp : (long)&tf->tf_rsp;
 #endif
-	rsp = (long)&tf->tf_rsp;
-
-	switch (frame_type) {
-	case TRAP:
-		{
-			rip = tf->tf_rip;
-			rbp = tf->tf_rbp;
-			db_printf(
-	    "--- trap %016lx, rip = %016lx, rsp = %016lx, rbp = %016lx ---\n",
-			    tf->tf_trapno, rip, rsp, rbp);
-		}
-		break;
-	case SYSCALL:
-		{
-			rip = tf->tf_rip;
-			rbp = tf->tf_rbp;
-			db_printf(
-	"--- syscall %016lx, rip = %016lx, rsp = %016lx, rbp = %016lx ---\n",
-			    tf->tf_rax, rip, rsp, rbp);
-		}
-		break;
-	case INTERRUPT:
-		tf = (struct trapframe *)((long)*fp + 16);
-		{
-			rip = tf->tf_rip;
-			rbp = tf->tf_rbp;
-			db_printf(
-	    "--- interrupt, rip = %016lx, rsp = %016lx, rbp = %016lx ---\n",
-			    rip, rsp, rbp);
-		}
-		break;
-	default:
+		rsp = (long)&tf->tf_rsp;
 		rip = tf->tf_rip;
 		rbp = tf->tf_rbp;
-		break;
-	}
 
+		switch (frame_type) {
+		case TRAP:
+			db_printf("--- trap %016lx, "
+				  "rip = %016lx, rsp = %016lx, rbp = %016lx "
+				  "---\n",
+				  tf->tf_trapno, rip, rsp, rbp);
+			break;
+		case SYSCALL:
+			db_printf("--- syscall %016lx, "
+				  "rip = %016lx, rsp = %016lx, rbp = %016lx "
+				  "---\n",
+				  tf->tf_rax, rip, rsp, rbp);
+			break;
+		case INTERRUPT:
+			db_printf("--- interrupt, "
+				  "rip = %016lx, rsp = %016lx, rbp = %016lx "
+				  "---\n",
+				  rip, rsp, rbp);
+			break;
+		default:
+			break;
+		}
+	}
 	*ip = (db_addr_t) rip;
 	*fp = (struct x86_64_frame *) rbp;
 }
@@ -331,6 +322,10 @@ db_stack_trace_cmd(db_expr_t addr, boolean_t have_addr, db_expr_t count,
 		if (frame == NULL)
 			frame = (struct x86_64_frame *)(SP_REGS(&ddb_regs) - 8);
 		callpc = PC_REGS(&ddb_regs);
+	} else if (!INKERNEL(addr)) {
+		/* XXX */
+		db_printf("no kernel stack address\n");
+		return;
 	} else {
 		/*
 		 * Look for something that might be a frame pointer, just as





More information about the Bugs mailing list