svn commit: r334122 - in head/sys: amd64/amd64 i386/i386 sys

Konstantin Belousov kib at FreeBSD.org
Wed May 23 21:39:31 UTC 2018


Author: kib
Date: Wed May 23 21:39:29 2018
New Revision: 334122
URL: https://svnweb.freebsd.org/changeset/base/334122

Log:
  x86: stop unconditionally clearing PSL_T on the trace trap.
  
  We certainly should clear PSL_T when calling the SIGTRAP signal
  handler, which is already done by all x86 sendsig(9) ABI code.  On the
  other hand, there is no obvious reason why PSL_T needs to be cleared
  when returning from the signal handler.  For instance, Linux allows
  userspace to set PSL_T and keep tracing enabled for the desired
  period.  There are userspace programs which would use PSL_T if we make
  it possible, for instance sbcl.
  
  Remember if PSL_T was set by PT_STEP or PT_SETSTEP by mean of TDB_STEP
  flag, and only clear it when the flag is set.
  
  Discussed with:	Ali Mashtizadeh
  Reviewed by:	jhb (previous version)
  Sponsored by:	The FreeBSD Foundation
  MFC after:	2 weeks
  Differential revision:	https://reviews.freebsd.org/D15054

Modified:
  head/sys/amd64/amd64/machdep.c
  head/sys/amd64/amd64/trap.c
  head/sys/i386/i386/machdep.c
  head/sys/i386/i386/trap.c
  head/sys/sys/proc.h

Modified: head/sys/amd64/amd64/machdep.c
==============================================================================
--- head/sys/amd64/amd64/machdep.c	Wed May 23 21:26:41 2018	(r334121)
+++ head/sys/amd64/amd64/machdep.c	Wed May 23 21:39:29 2018	(r334122)
@@ -1978,7 +1978,12 @@ ptrace_set_pc(struct thread *td, unsigned long addr)
 int
 ptrace_single_step(struct thread *td)
 {
-	td->td_frame->tf_rflags |= PSL_T;
+
+	PROC_LOCK_ASSERT(td->td_proc, MA_OWNED);
+	if ((td->td_frame->tf_rflags & PSL_T) == 0) {
+		td->td_frame->tf_rflags |= PSL_T;
+		td->td_dbgflags |= TDB_STEP;
+	}
 	return (0);
 }
 
@@ -1986,7 +1991,9 @@ int
 ptrace_clear_single_step(struct thread *td)
 {
 
+	PROC_LOCK_ASSERT(td->td_proc, MA_OWNED);
 	td->td_frame->tf_rflags &= ~PSL_T;
+	td->td_dbgflags &= ~TDB_STEP;
 	return (0);
 }
 

Modified: head/sys/amd64/amd64/trap.c
==============================================================================
--- head/sys/amd64/amd64/trap.c	Wed May 23 21:26:41 2018	(r334121)
+++ head/sys/amd64/amd64/trap.c	Wed May 23 21:39:29 2018	(r334122)
@@ -285,8 +285,14 @@ trap(struct trapframe *frame)
 			signo = SIGTRAP;
 			ucode = TRAP_TRACE;
 			dr6 = rdr6();
-			if (dr6 & DBREG_DR6_BS)
-				frame->tf_rflags &= ~PSL_T;
+			if ((dr6 & DBREG_DR6_BS) != 0) {
+				PROC_LOCK(td->td_proc);
+				if ((td->td_dbgflags & TDB_STEP) != 0) {
+					td->td_frame->tf_rflags &= ~PSL_T;
+					td->td_dbgflags &= ~TDB_STEP;
+				}
+				PROC_UNLOCK(td->td_proc);
+			}
 			break;
 
 		case T_ARITHTRAP:	/* arithmetic trap */

Modified: head/sys/i386/i386/machdep.c
==============================================================================
--- head/sys/i386/i386/machdep.c	Wed May 23 21:26:41 2018	(r334121)
+++ head/sys/i386/i386/machdep.c	Wed May 23 21:39:29 2018	(r334122)
@@ -2764,7 +2764,12 @@ ptrace_set_pc(struct thread *td, u_long addr)
 int
 ptrace_single_step(struct thread *td)
 {
-	td->td_frame->tf_eflags |= PSL_T;
+
+	PROC_LOCK_ASSERT(td->td_proc, MA_OWNED);
+	if ((td->td_frame->tf_eflags & PSL_T) == 0) {
+		td->td_frame->tf_eflags |= PSL_T;
+		td->td_dbgflags |= TDB_STEP;
+	}
 	return (0);
 }
 
@@ -2772,7 +2777,9 @@ int
 ptrace_clear_single_step(struct thread *td)
 {
 
+	PROC_LOCK_ASSERT(td->td_proc, MA_OWNED);
 	td->td_frame->tf_eflags &= ~PSL_T;
+	td->td_dbgflags &= ~TDB_STEP;
 	return (0);
 }
 

Modified: head/sys/i386/i386/trap.c
==============================================================================
--- head/sys/i386/i386/trap.c	Wed May 23 21:26:41 2018	(r334121)
+++ head/sys/i386/i386/trap.c	Wed May 23 21:39:29 2018	(r334122)
@@ -337,8 +337,14 @@ user_trctrap_out:
 			signo = SIGTRAP;
 			ucode = TRAP_TRACE;
 			dr6 = rdr6();
-			if (dr6 & DBREG_DR6_BS)
-				frame->tf_eflags &= ~PSL_T;
+			if ((dr6 & DBREG_DR6_BS) != 0) {
+				PROC_LOCK(td->td_proc);
+				if ((td->td_dbgflags & TDB_STEP) != 0) {
+					td->td_frame->tf_eflags &= ~PSL_T;
+					td->td_dbgflags &= ~TDB_STEP;
+				}
+				PROC_UNLOCK(td->td_proc);
+			}
 			break;
 
 		case T_ARITHTRAP:	/* arithmetic trap */

Modified: head/sys/sys/proc.h
==============================================================================
--- head/sys/sys/proc.h	Wed May 23 21:26:41 2018	(r334121)
+++ head/sys/sys/proc.h	Wed May 23 21:39:29 2018	(r334122)
@@ -465,6 +465,7 @@ do {									\
 #define	TDB_EXIT	0x00000400 /* Exiting LWP indicator for ptrace() */
 #define	TDB_VFORK	0x00000800 /* vfork indicator for ptrace() */
 #define	TDB_FSTP	0x00001000 /* The thread is PT_ATTACH leader */
+#define	TDB_STEP	0x00002000 /* (x86) PSL_T set for PT_STEP */
 
 /*
  * "Private" flags kept in td_pflags:


More information about the svn-src-head mailing list