diff --git a/sys/kern/subr_syscall.c b/sys/kern/subr_syscall.c --- a/sys/kern/subr_syscall.c +++ b/sys/kern/subr_syscall.c @@ -56,7 +56,7 @@ struct syscall_args *sa; struct sysent *se; int error; - bool sy_thr_static, traced; + bool do_set_rv, sy_thr_static, traced; VM_CNT_INC(v_syscall); p = td->td_proc; @@ -98,6 +98,10 @@ PROC_UNLOCK(p); if ((td->td_dbgflags & TDB_USERWR) != 0) { + PROC_LOCK(p); + td->td_dbgflags &= ~TDB_USERWR; + PROC_UNLOCK(p); + /* * Reread syscall number and arguments if debugger * modified registers or memory. @@ -203,12 +207,16 @@ (uintptr_t)td, "pid:%d", td->td_proc->p_pid, "error:%d", error, "retval0:%#lx", td->td_retval[0], "retval1:%#lx", td->td_retval[1]); + do_set_rv = true; if (__predict_false(traced)) { PROC_LOCK(p); - td->td_dbgflags &= ~(TDB_SCE | TDB_BOUNDARY); + if ((td->td_dbgflags & TDB_USERWR) != 0) + do_set_rv = false; + td->td_dbgflags &= ~(TDB_SCE | TDB_BOUNDARY | TDB_USERWR); PROC_UNLOCK(p); } - (p->p_sysent->sv_set_syscall_retval)(td, error); + if (__predict_true(do_set_rv)) + (p->p_sysent->sv_set_syscall_retval)(td, error); if (error != 0 && (td->td_pflags2 & TDP2_UEXTERR) != 0) exterr_copyout(td); }