diff options
author | Denys Vlasenko <dvlasenk@redhat.com> | 2012-01-18 16:30:47 +0100 |
---|---|---|
committer | Denys Vlasenko <dvlasenk@redhat.com> | 2012-01-18 16:30:47 +0100 |
commit | 023b7700de942f59fcb4cd30903969d276a4d796 (patch) | |
tree | 4c941e2a8bd47ef25b2db2f45d042ce2c4f63def | |
parent | 5e09d77500a656da343580a16e6d005eb1c560b1 (diff) | |
download | strace-023b7700de942f59fcb4cd30903969d276a4d796.tar.gz |
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>
-rw-r--r-- | defs.h | 1 | ||||
-rw-r--r-- | signal.c | 52 | ||||
-rw-r--r-- | strace.c | 9 |
3 files changed, 3 insertions, 59 deletions
@@ -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 @@ -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; @@ -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; |