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-all
mailing list