Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 21 Jul 2015 23:22:24 +0000 (UTC)
From:      Mark Johnston <markj@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r285776 - in head/sys: amd64/amd64 i386/i386
Message-ID:  <201507212322.t6LNMOLb011251@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: markj
Date: Tue Jul 21 23:22:23 2015
New Revision: 285776
URL: https://svnweb.freebsd.org/changeset/base/285776

Log:
  Let the unwinder handle faults during function prologues or epilogues.
  
  The i386 and amd64 DDB stack unwinders contain code to detect and handle
  the case where the first frame is not completely set up or torn down. This
  code was accidentally unused however, since db_backtrace() was never called
  with a non-NULL trap frame. This change fixes that.
  
  Also remove get_rsp() from the amd64 code. It appears to have come from
  i386, which needs to take into account whether the exception triggered a
  CPL switch, since SS:ESP is only pushed onto the stack if so. On amd64,
  SS:RSP is pushed regardless, so get_rsp() was doing the wrong thing for
  kernel-mode exceptions. As a result, we can also remove custom print
  functions for these registers.
  
  Reviewed by:	jhb
  Sponsored by:	EMC / Isilon Storage Division
  Differential Revision:	https://reviews.freebsd.org/D2881

Modified:
  head/sys/amd64/amd64/db_trace.c
  head/sys/i386/i386/db_trace.c

Modified: head/sys/amd64/amd64/db_trace.c
==============================================================================
--- head/sys/amd64/amd64/db_trace.c	Tue Jul 21 23:13:11 2015	(r285775)
+++ head/sys/amd64/amd64/db_trace.c	Tue Jul 21 23:22:23 2015	(r285776)
@@ -61,8 +61,6 @@ static db_varfcn_t db_dr5;
 static db_varfcn_t db_dr6;
 static db_varfcn_t db_dr7;
 static db_varfcn_t db_frame;
-static db_varfcn_t db_rsp;
-static db_varfcn_t db_ss;
 
 CTASSERT(sizeof(struct dbreg) == sizeof(((struct pcpu *)NULL)->pc_dbreg));
 
@@ -76,12 +74,12 @@ struct db_variable db_regs[] = {
 	{ "es",		DB_OFFSET(tf_es),	db_frame },
 	{ "fs",		DB_OFFSET(tf_fs),	db_frame },
 	{ "gs",		DB_OFFSET(tf_gs),	db_frame },
-	{ "ss",		NULL,			db_ss },
+	{ "ss",		DB_OFFSET(tf_ss),	db_frame },
 	{ "rax",	DB_OFFSET(tf_rax),	db_frame },
 	{ "rcx",        DB_OFFSET(tf_rcx),	db_frame },
 	{ "rdx",	DB_OFFSET(tf_rdx),	db_frame },
 	{ "rbx",	DB_OFFSET(tf_rbx),	db_frame },
-	{ "rsp",	NULL,			db_rsp },
+	{ "rsp",	DB_OFFSET(tf_rsp),	db_frame },
 	{ "rbp",	DB_OFFSET(tf_rbp),	db_frame },
 	{ "rsi",	DB_OFFSET(tf_rsi),	db_frame },
 	{ "rdi",	DB_OFFSET(tf_rdi),	db_frame },
@@ -130,13 +128,6 @@ DB_DRX_FUNC(dr5)
 DB_DRX_FUNC(dr6)
 DB_DRX_FUNC(dr7)
 
-static __inline long
-get_rsp(struct trapframe *tf)
-{
-	return ((ISPL(tf->tf_cs)) ? tf->tf_rsp :
-	    (db_expr_t)tf + offsetof(struct trapframe, tf_rsp));
-}
-
 static int
 db_frame(struct db_variable *vp, db_expr_t *valuep, int op)
 {
@@ -153,34 +144,6 @@ db_frame(struct db_variable *vp, db_expr
 	return (1);
 }
 
-static int
-db_rsp(struct db_variable *vp, db_expr_t *valuep, int op)
-{
-
-	if (kdb_frame == NULL)
-		return (0);
-
-	if (op == DB_VAR_GET)
-		*valuep = get_rsp(kdb_frame);
-	else if (ISPL(kdb_frame->tf_cs))
-		kdb_frame->tf_rsp = *valuep;
-	return (1);
-}
-
-static int
-db_ss(struct db_variable *vp, db_expr_t *valuep, int op)
-{
-
-	if (kdb_frame == NULL)
-		return (0);
-
-	if (op == DB_VAR_GET)
-		*valuep = (ISPL(kdb_frame->tf_cs)) ? kdb_frame->tf_ss : rss();
-	else if (ISPL(kdb_frame->tf_cs))
-		kdb_frame->tf_ss = *valuep;
-	return (1);
-}
-
 #define NORMAL		0
 #define	TRAP		1
 #define	INTERRUPT	2
@@ -304,7 +267,7 @@ db_nextframe(struct amd64_frame **fp, db
 	tf = (struct trapframe *)((long)*fp + 16);
 
 	if (INKERNEL((long) tf)) {
-		rsp = get_rsp(tf);
+		rsp = tf->tf_rsp;
 		rip = tf->tf_rip;
 		rbp = tf->tf_rbp;
 		switch (frame_type) {
@@ -380,20 +343,20 @@ db_backtrace(struct thread *td, struct t
 				instr = db_get_value(pc, 4, FALSE);
 				if ((instr & 0xffffffff) == 0xe5894855) {
 					/* pushq %rbp; movq %rsp, %rbp */
-					actframe = (void *)(get_rsp(tf) - 8);
+					actframe = (void *)(tf->tf_rsp - 8);
 				} else if ((instr & 0xffffff) == 0xe58948) {
 					/* movq %rsp, %rbp */
-					actframe = (void *)get_rsp(tf);
+					actframe = (void *)tf->tf_rsp;
 					if (tf->tf_rbp == 0) {
 						/* Fake frame better. */
 						frame = actframe;
 					}
 				} else if ((instr & 0xff) == 0xc3) {
 					/* ret */
-					actframe = (void *)(get_rsp(tf) - 8);
+					actframe = (void *)(tf->tf_rsp - 8);
 				} else if (offset == 0) {
 					/* Probably an assembler symbol. */
-					actframe = (void *)(get_rsp(tf) - 8);
+					actframe = (void *)(tf->tf_rsp - 8);
 				}
 			} else if (strcmp(name, "fork_trampoline") == 0) {
 				/*
@@ -448,9 +411,11 @@ int
 db_trace_thread(struct thread *thr, int count)
 {
 	struct pcb *ctx;
+	struct trapframe *tf;
 
 	ctx = kdb_thr_ctx(thr);
-	return (db_backtrace(thr, NULL, (struct amd64_frame *)ctx->pcb_rbp,
+	tf = thr == kdb_thread ? kdb_frame : NULL;
+	return (db_backtrace(thr, tf, (struct amd64_frame *)ctx->pcb_rbp,
 	    ctx->pcb_rip, ctx->pcb_rsp, count));
 }
 

Modified: head/sys/i386/i386/db_trace.c
==============================================================================
--- head/sys/i386/i386/db_trace.c	Tue Jul 21 23:13:11 2015	(r285775)
+++ head/sys/i386/i386/db_trace.c	Tue Jul 21 23:22:23 2015	(r285776)
@@ -541,9 +541,11 @@ int
 db_trace_thread(struct thread *thr, int count)
 {
 	struct pcb *ctx;
+	struct trapframe *tf;
 
 	ctx = kdb_thr_ctx(thr);
-	return (db_backtrace(thr, NULL, (struct i386_frame *)ctx->pcb_ebp,
+	tf = thr == kdb_thread ? kdb_frame : NULL;
+	return (db_backtrace(thr, tf, (struct i386_frame *)ctx->pcb_ebp,
 	    ctx->pcb_eip, ctx->pcb_esp, count));
 }
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201507212322.t6LNMOLb011251>