Get rid of TCB_SIGTRAPPED
On attempts to block or set SIGTRAP handler, for example, using sigaction syscall, we generate an additional SIGSTOP. This change gets rid of this SIGSTOP sending/ignoring. It appears to work just fine. It also works if I force strace to not use PTRACE_O_TRACESYSGOOD, which means strace stops will be marked with SIGTRAP, not (SIGTRAP | 0x80) - I wondered maybe that's when this hack is needed. So, why we even have TCB_SIGTRAPPED? No one knows. It predates version control: this code was present in the initial commit, in 1999. No adequate comments, either. Moreover, TCB_SIGTRAPPED is not set in sys_rt_sigaction and sys_sigprocmask syscalls - the ones which are most usually used to implement signal blocking, it is only set in obsolete sys_signal, sys_sigaction, sys_sigsetmask, and in some dead non-Linux code. I think whatever bug it was fixing is gone long ago - at least as long as sys_rt_sigaction is used by glibc. Again, since glibc (and uclibc) uses sys_rt_sigaction and sys_sigprocmask, modified code paths are not used by most programs anyway. * defs.h: Remove definition of TCB_SIGTRAPPED. * signal.c (sys_sigvec): Don't set TCB_SIGTRAPPED and don't send SIGSTOP. (sys_sigsetmask): Likewise. (sys_sigaction): Likewise. (sys_signal): Likewise. * strace.c (trace): Remove code which executes if TCB_SIGTRAPPED is set. Signed-off-by: Denys Vlasenko <dvlasenk@redhat.com>
This commit is contained in:
parent
5e09d77500
commit
023b7700de
1
defs.h
1
defs.h
@ -475,7 +475,6 @@ struct tcb {
|
||||
#define TCB_INSYSCALL 00010
|
||||
#define TCB_ATTACHED 00020 /* Process is not our own child */
|
||||
#define TCB_BPTSET 00100 /* "Breakpoint" set after fork(2) */
|
||||
#define TCB_SIGTRAPPED 00200 /* Process wanted to block SIGTRAP */
|
||||
#define TCB_REPRINT 01000 /* We should reprint this syscall on exit */
|
||||
#define TCB_FILTERED 02000 /* This system call has been filtered out */
|
||||
#ifdef LINUX
|
||||
|
52
signal.c
52
signal.c
@ -842,24 +842,12 @@ sys_sigvec(struct tcb *tcp)
|
||||
tprints("{SIG_DFL}");
|
||||
break;
|
||||
case (int) SIG_IGN:
|
||||
if (tcp->u_arg[0] == SIGTRAP) {
|
||||
tcp->flags |= TCB_SIGTRAPPED;
|
||||
kill(tcp->pid, SIGSTOP);
|
||||
}
|
||||
tprints("{SIG_IGN}");
|
||||
break;
|
||||
case (int) SIG_HOLD:
|
||||
if (tcp->u_arg[0] == SIGTRAP) {
|
||||
tcp->flags |= TCB_SIGTRAPPED;
|
||||
kill(tcp->pid, SIGSTOP);
|
||||
}
|
||||
tprints("SIG_HOLD");
|
||||
tprints("{SIG_HOLD}");
|
||||
break;
|
||||
default:
|
||||
if (tcp->u_arg[0] == SIGTRAP) {
|
||||
tcp->flags |= TCB_SIGTRAPPED;
|
||||
kill(tcp->pid, SIGSTOP);
|
||||
}
|
||||
tprintf("{%#lx, ", (unsigned long) sv.sv_handler);
|
||||
printsigmask(&sv.sv_mask, 0);
|
||||
tprints(", ");
|
||||
@ -923,14 +911,6 @@ sys_sigsetmask(struct tcb *tcp)
|
||||
sigset_t sigm;
|
||||
long_to_sigset(tcp->u_arg[0], &sigm);
|
||||
printsigmask(&sigm, 0);
|
||||
#ifndef USE_PROCFS
|
||||
if ((tcp->u_arg[0] & sigmask(SIGTRAP))) {
|
||||
/* Mark attempt to block SIGTRAP */
|
||||
tcp->flags |= TCB_SIGTRAPPED;
|
||||
/* Send unblockable signal */
|
||||
kill(tcp->pid, SIGSTOP);
|
||||
}
|
||||
#endif /* !USE_PROCFS */
|
||||
}
|
||||
else if (!syserror(tcp)) {
|
||||
sigset_t sigm;
|
||||
@ -1005,24 +985,10 @@ sys_sigaction(struct tcb *tcp)
|
||||
tprints("{SIG_ERR, ");
|
||||
else if ((long)sa.SA_HANDLER == (long)SIG_DFL)
|
||||
tprints("{SIG_DFL, ");
|
||||
else if ((long)sa.SA_HANDLER == (long)SIG_IGN) {
|
||||
#ifndef USE_PROCFS
|
||||
if (tcp->u_arg[0] == SIGTRAP) {
|
||||
tcp->flags |= TCB_SIGTRAPPED;
|
||||
kill(tcp->pid, SIGSTOP);
|
||||
}
|
||||
#endif /* !USE_PROCFS */
|
||||
else if ((long)sa.SA_HANDLER == (long)SIG_IGN)
|
||||
tprints("{SIG_IGN, ");
|
||||
}
|
||||
else {
|
||||
#ifndef USE_PROCFS
|
||||
if (tcp->u_arg[0] == SIGTRAP) {
|
||||
tcp->flags |= TCB_SIGTRAPPED;
|
||||
kill(tcp->pid, SIGSTOP);
|
||||
}
|
||||
#endif /* !USE_PROCFS */
|
||||
else
|
||||
tprintf("{%#lx, ", (long) sa.SA_HANDLER);
|
||||
}
|
||||
#ifndef LINUX
|
||||
printsigmask(&sa.sa_mask, 0);
|
||||
#else
|
||||
@ -1060,21 +1026,9 @@ sys_signal(struct tcb *tcp)
|
||||
tprints("SIG_DFL");
|
||||
break;
|
||||
case (long) SIG_IGN:
|
||||
#ifndef USE_PROCFS
|
||||
if (tcp->u_arg[0] == SIGTRAP) {
|
||||
tcp->flags |= TCB_SIGTRAPPED;
|
||||
kill(tcp->pid, SIGSTOP);
|
||||
}
|
||||
#endif /* !USE_PROCFS */
|
||||
tprints("SIG_IGN");
|
||||
break;
|
||||
default:
|
||||
#ifndef USE_PROCFS
|
||||
if (tcp->u_arg[0] == SIGTRAP) {
|
||||
tcp->flags |= TCB_SIGTRAPPED;
|
||||
kill(tcp->pid, SIGSTOP);
|
||||
}
|
||||
#endif /* !USE_PROCFS */
|
||||
tprintf("%#lx", tcp->u_arg[1]);
|
||||
}
|
||||
return 0;
|
||||
|
9
strace.c
9
strace.c
@ -2542,15 +2542,6 @@ trace()
|
||||
}
|
||||
|
||||
if (sig != syscall_trap_sig) {
|
||||
if (sig == SIGSTOP &&
|
||||
(tcp->flags & TCB_SIGTRAPPED)) {
|
||||
/*
|
||||
* Trapped attempt to block SIGTRAP
|
||||
* Hope we are back in control now.
|
||||
*/
|
||||
tcp->flags &= ~(TCB_INSYSCALL | TCB_SIGTRAPPED);
|
||||
goto restart_tracee_with_sig_0;
|
||||
}
|
||||
if (cflag != CFLAG_ONLY_STATS
|
||||
&& (qual_flags[sig] & QUAL_SIGNAL)) {
|
||||
siginfo_t si;
|
||||
|
Loading…
x
Reference in New Issue
Block a user