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:
_______________________________________________
svn-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to