diff options
author | Konstantin Belousov <kib@FreeBSD.org> | 2018-05-23 21:39:29 +0000 |
---|---|---|
committer | Konstantin Belousov <kib@FreeBSD.org> | 2018-05-23 21:39:29 +0000 |
commit | 8936419a6c842c065c8d831151cb7cc61dea28f6 (patch) | |
tree | 8c4de6fb77e1c7e04632bbca1b8251a776c23573 /sys/amd64/amd64/trap.c | |
parent | 79547c52b8288671c5984eaa5d5ca34a3a77dabd (diff) | |
download | src-8936419a6c842c065c8d831151cb7cc61dea28f6.tar.gz src-8936419a6c842c065c8d831151cb7cc61dea28f6.zip |
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
Notes
Notes:
svn path=/head/; revision=334122
Diffstat (limited to 'sys/amd64/amd64/trap.c')
-rw-r--r-- | sys/amd64/amd64/trap.c | 10 |
1 files changed, 8 insertions, 2 deletions
diff --git a/sys/amd64/amd64/trap.c b/sys/amd64/amd64/trap.c index 8e4d411b3435..dfa38fb1376f 100644 --- a/sys/amd64/amd64/trap.c +++ b/sys/amd64/amd64/trap.c @@ -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 */ |