Skip to content

Commit

Permalink
Clear the single-step flag for signal handlers. This fixes bogus trace
Browse files Browse the repository at this point in the history
traps on the first instruction of signal handlers.

In trap.c:syscall(), fake a trace trap if the single-step flag was set
on entry to the kernel, not if it will be set on exit from the kernel.
This fixes bogus trace traps after the last instruction of signal handlers.

gdb-4.18 (the version in FreeBSD) still has problems with the program in
the PR.  These seem to be due to bugs in gdb and not in FreeBSD, and are
fixed in gdb-5.1 (the distribution version).

PR:		33262
Tested by:	k Macy <kip_macy@yahoo.com>
MFC after:	1 day
  • Loading branch information
Bruce Evans authored and Bruce Evans committed Jan 10, 2002
1 parent 52f1d68 commit 846ac22
Show file tree
Hide file tree
Showing 8 changed files with 25 additions and 28 deletions.
10 changes: 4 additions & 6 deletions sys/amd64/amd64/machdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ osendsig(catcher, sig, mask, code)
(vm86->vm86_eflags & (PSL_VIF | PSL_VIP));

/* See sendsig() for comments. */
tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_T | PSL_VIF | PSL_VIP);
tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_VIF | PSL_VIP);
}

/* Copy the sigframe out to the user's stack. */
Expand All @@ -417,6 +417,7 @@ osendsig(catcher, sig, mask, code)

regs->tf_esp = (int)fp;
regs->tf_eip = PS_STRINGS - szosigcode;
regs->tf_eflags &= ~PSL_T;
regs->tf_cs = _ucodesel;
regs->tf_ds = _udatasel;
regs->tf_es = _udatasel;
Expand Down Expand Up @@ -546,17 +547,13 @@ sendsig(catcher, sig, mask, code)
(vm86->vm86_eflags & (PSL_VIF | PSL_VIP));

/*
* We should never have PSL_T set when returning from vm86
* mode. It may be set here if we deliver a signal before
* getting to vm86 mode, so turn it off.
*
* Clear PSL_NT to inhibit T_TSSFLT faults on return from
* syscalls made by the signal handler. This just avoids
* wasting time for our lazy fixup of such faults. PSL_NT
* does nothing in vm86 mode, but vm86 programs can set it
* almost legitimately in probes for old cpu types.
*/
tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_T | PSL_VIF | PSL_VIP);
tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_VIF | PSL_VIP);
}

/* Copy the sigframe out to the user's stack. */
Expand All @@ -572,6 +569,7 @@ sendsig(catcher, sig, mask, code)

regs->tf_esp = (int)sfp;
regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode);
regs->tf_eflags &= ~PSL_T;
regs->tf_cs = _ucodesel;
regs->tf_ds = _udatasel;
regs->tf_es = _udatasel;
Expand Down
4 changes: 3 additions & 1 deletion sys/amd64/amd64/trap.c
Original file line number Diff line number Diff line change
Expand Up @@ -933,6 +933,7 @@ syscall(frame)
struct sysent *callp;
struct thread *td = curthread;
struct proc *p = td->td_proc;
register_t orig_tf_eflags;
u_int sticks;
int error;
int narg;
Expand All @@ -958,6 +959,7 @@ syscall(frame)
PROC_UNLOCK(p);
params = (caddr_t)frame.tf_esp + sizeof(int);
code = frame.tf_eax;
orig_tf_eflags = frame.tf_eflags;

if (p->p_sysent->sv_prepsyscall) {
/*
Expand Down Expand Up @@ -1065,7 +1067,7 @@ syscall(frame)
/*
* Traced syscall.
*/
if ((frame.tf_eflags & PSL_T) && !(frame.tf_eflags & PSL_VM)) {
if ((orig_tf_eflags & PSL_T) && !(orig_tf_eflags & PSL_VM)) {
frame.tf_eflags &= ~PSL_T;
trapsignal(p, SIGTRAP, 0);
}
Expand Down
10 changes: 4 additions & 6 deletions sys/i386/i386/machdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ osendsig(catcher, sig, mask, code)
(vm86->vm86_eflags & (PSL_VIF | PSL_VIP));

/* See sendsig() for comments. */
tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_T | PSL_VIF | PSL_VIP);
tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_VIF | PSL_VIP);
}

/* Copy the sigframe out to the user's stack. */
Expand All @@ -417,6 +417,7 @@ osendsig(catcher, sig, mask, code)

regs->tf_esp = (int)fp;
regs->tf_eip = PS_STRINGS - szosigcode;
regs->tf_eflags &= ~PSL_T;
regs->tf_cs = _ucodesel;
regs->tf_ds = _udatasel;
regs->tf_es = _udatasel;
Expand Down Expand Up @@ -546,17 +547,13 @@ sendsig(catcher, sig, mask, code)
(vm86->vm86_eflags & (PSL_VIF | PSL_VIP));

/*
* We should never have PSL_T set when returning from vm86
* mode. It may be set here if we deliver a signal before
* getting to vm86 mode, so turn it off.
*
* Clear PSL_NT to inhibit T_TSSFLT faults on return from
* syscalls made by the signal handler. This just avoids
* wasting time for our lazy fixup of such faults. PSL_NT
* does nothing in vm86 mode, but vm86 programs can set it
* almost legitimately in probes for old cpu types.
*/
tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_T | PSL_VIF | PSL_VIP);
tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_VIF | PSL_VIP);
}

/* Copy the sigframe out to the user's stack. */
Expand All @@ -572,6 +569,7 @@ sendsig(catcher, sig, mask, code)

regs->tf_esp = (int)sfp;
regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode);
regs->tf_eflags &= ~PSL_T;
regs->tf_cs = _ucodesel;
regs->tf_ds = _udatasel;
regs->tf_es = _udatasel;
Expand Down
4 changes: 3 additions & 1 deletion sys/i386/i386/trap.c
Original file line number Diff line number Diff line change
Expand Up @@ -933,6 +933,7 @@ syscall(frame)
struct sysent *callp;
struct thread *td = curthread;
struct proc *p = td->td_proc;
register_t orig_tf_eflags;
u_int sticks;
int error;
int narg;
Expand All @@ -958,6 +959,7 @@ syscall(frame)
PROC_UNLOCK(p);
params = (caddr_t)frame.tf_esp + sizeof(int);
code = frame.tf_eax;
orig_tf_eflags = frame.tf_eflags;

if (p->p_sysent->sv_prepsyscall) {
/*
Expand Down Expand Up @@ -1065,7 +1067,7 @@ syscall(frame)
/*
* Traced syscall.
*/
if ((frame.tf_eflags & PSL_T) && !(frame.tf_eflags & PSL_VM)) {
if ((orig_tf_eflags & PSL_T) && !(orig_tf_eflags & PSL_VM)) {
frame.tf_eflags &= ~PSL_T;
trapsignal(p, SIGTRAP, 0);
}
Expand Down
4 changes: 2 additions & 2 deletions sys/i386/linux/linux_sysvec.c
Original file line number Diff line number Diff line change
Expand Up @@ -385,7 +385,7 @@ linux_rt_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
regs->tf_esp = (int)fp;
regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode) +
linux_sznonrtsigcode;
regs->tf_eflags &= ~PSL_VM;
regs->tf_eflags &= ~(PSL_T | PSL_VM);
regs->tf_cs = _ucodesel;
regs->tf_ds = _udatasel;
regs->tf_es = _udatasel;
Expand Down Expand Up @@ -519,7 +519,7 @@ linux_sendsig(sig_t catcher, int sig, sigset_t *mask, u_long code)
*/
regs->tf_esp = (int)fp;
regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode);
regs->tf_eflags &= ~PSL_VM;
regs->tf_eflags &= ~(PSL_T | PSL_VM);
regs->tf_cs = _ucodesel;
regs->tf_ds = _udatasel;
regs->tf_es = _udatasel;
Expand Down
1 change: 1 addition & 0 deletions sys/i386/svr4/svr4_machdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,7 @@ svr4_sendsig(catcher, sig, mask, code)
#else
tf->tf_esp = (int)fp;
tf->tf_eip = (int)(((char *)PS_STRINGS) - *(p->p_sysent->sv_szsigcode));
tf->tf_eflags &= ~PSL_T;
tf->tf_cs = _ucodesel;
tf->tf_ds = _udatasel;
tf->tf_es = _udatasel;
Expand Down
10 changes: 4 additions & 6 deletions sys/pc98/i386/machdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ osendsig(catcher, sig, mask, code)
(vm86->vm86_eflags & (PSL_VIF | PSL_VIP));

/* See sendsig() for comments. */
tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_T | PSL_VIF | PSL_VIP);
tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_VIF | PSL_VIP);
}

/* Copy the sigframe out to the user's stack. */
Expand All @@ -430,6 +430,7 @@ osendsig(catcher, sig, mask, code)

regs->tf_esp = (int)fp;
regs->tf_eip = PS_STRINGS - szosigcode;
regs->tf_eflags &= ~PSL_T;
regs->tf_cs = _ucodesel;
regs->tf_ds = _udatasel;
regs->tf_es = _udatasel;
Expand Down Expand Up @@ -558,17 +559,13 @@ sendsig(catcher, sig, mask, code)
(vm86->vm86_eflags & (PSL_VIF | PSL_VIP));

/*
* We should never have PSL_T set when returning from vm86
* mode. It may be set here if we deliver a signal before
* getting to vm86 mode, so turn it off.
*
* Clear PSL_NT to inhibit T_TSSFLT faults on return from
* syscalls made by the signal handler. This just avoids
* wasting time for our lazy fixup of such faults. PSL_NT
* does nothing in vm86 mode, but vm86 programs can set it
* almost legitimately in probes for old cpu types.
*/
tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_T | PSL_VIF | PSL_VIP);
tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_VIF | PSL_VIP);
}

/* Copy the sigframe out to the user's stack. */
Expand All @@ -584,6 +581,7 @@ sendsig(catcher, sig, mask, code)

regs->tf_esp = (int)sfp;
regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode);
regs->tf_eflags &= ~PSL_T;
regs->tf_cs = _ucodesel;
regs->tf_ds = _udatasel;
regs->tf_es = _udatasel;
Expand Down
10 changes: 4 additions & 6 deletions sys/pc98/pc98/machdep.c
Original file line number Diff line number Diff line change
Expand Up @@ -414,7 +414,7 @@ osendsig(catcher, sig, mask, code)
(vm86->vm86_eflags & (PSL_VIF | PSL_VIP));

/* See sendsig() for comments. */
tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_T | PSL_VIF | PSL_VIP);
tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_VIF | PSL_VIP);
}

/* Copy the sigframe out to the user's stack. */
Expand All @@ -430,6 +430,7 @@ osendsig(catcher, sig, mask, code)

regs->tf_esp = (int)fp;
regs->tf_eip = PS_STRINGS - szosigcode;
regs->tf_eflags &= ~PSL_T;
regs->tf_cs = _ucodesel;
regs->tf_ds = _udatasel;
regs->tf_es = _udatasel;
Expand Down Expand Up @@ -558,17 +559,13 @@ sendsig(catcher, sig, mask, code)
(vm86->vm86_eflags & (PSL_VIF | PSL_VIP));

/*
* We should never have PSL_T set when returning from vm86
* mode. It may be set here if we deliver a signal before
* getting to vm86 mode, so turn it off.
*
* Clear PSL_NT to inhibit T_TSSFLT faults on return from
* syscalls made by the signal handler. This just avoids
* wasting time for our lazy fixup of such faults. PSL_NT
* does nothing in vm86 mode, but vm86 programs can set it
* almost legitimately in probes for old cpu types.
*/
tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_T | PSL_VIF | PSL_VIP);
tf->tf_eflags &= ~(PSL_VM | PSL_NT | PSL_VIF | PSL_VIP);
}

/* Copy the sigframe out to the user's stack. */
Expand All @@ -584,6 +581,7 @@ sendsig(catcher, sig, mask, code)

regs->tf_esp = (int)sfp;
regs->tf_eip = PS_STRINGS - *(p->p_sysent->sv_szsigcode);
regs->tf_eflags &= ~PSL_T;
regs->tf_cs = _ucodesel;
regs->tf_ds = _udatasel;
regs->tf_es = _udatasel;
Expand Down

0 comments on commit 846ac22

Please sign in to comment.