static void detach(struct tcb *tcp);
static void cleanup(void);
static void interrupt(int sig);
-static sigset_t start_set, blocked_set;
#ifdef HAVE_SIG_ATOMIC_T
static volatile sig_atomic_t interrupted;
unsigned int tcbi;
struct tcb *tcp;
- /*
- * Block user interruptions as we would leave the traced
- * process stopped (process state T) if we would terminate in
- * between PTRACE_ATTACH and wait4() on SIGSTOP.
- * We rely on cleanup() from this point on.
- */
- if (interactive)
- sigprocmask(SIG_SETMASK, &blocked_set, NULL);
-
if (daemonized_tracer) {
pid_t pid = fork();
if (pid < 0)
attach_tcb(tcp);
- if (interactive) {
- sigprocmask(SIG_SETMASK, &start_set, NULL);
- if (interrupted)
- goto ret;
- sigprocmask(SIG_SETMASK, &blocked_set, NULL);
- }
+ if (interrupted)
+ return;
} /* for each tcbtab[] */
if (daemonized_tracer) {
kill(parent_pid, SIGKILL);
strace_child = 0;
}
-
- ret:
- if (interactive)
- sigprocmask(SIG_SETMASK, &start_set, NULL);
}
/* Stack-o-phobic exec helper, in the hope to work around
static void
set_sighandler(int signo, void (*sighandler)(int), struct sigaction *oldact)
{
- /* if signal handler is a function, add the signal to blocked_set */
- if (sighandler != SIG_IGN && sighandler != SIG_DFL)
- sigaddset(&blocked_set, signo);
-
const struct sigaction sa = { .sa_handler = sighandler };
sigaction(signo, &sa, oldact);
}
memset(acolumn_spaces, ' ', acolumn);
acolumn_spaces[acolumn] = '\0';
- sigprocmask(SIG_SETMASK, NULL, &start_set);
- memcpy(&blocked_set, &start_set, sizeof(blocked_set));
-
set_sighandler(SIGCHLD, SIG_DFL, ¶ms_for_tracee.child_sa);
#ifdef USE_LIBUNWIND
set_sighandler(SIGTSTP, SIG_IGN, NULL);
/*
* In interactive mode (if no -o OUTFILE, or -p PID is used),
- * fatal signals are blocked while syscall stop is processed,
- * and acted on in between, when waiting for new syscall stops.
- * In non-interactive mode, signals are ignored.
+ * fatal signals are handled asynchronously and acted
+ * when waiting for process state changes.
+ * In non-interactive mode these signals are ignored.
*/
set_sighandler(SIGHUP, interactive ? interrupt : SIG_IGN, NULL);
set_sighandler(SIGINT, interactive ? interrupt : SIG_IGN, NULL);
next_event(int *pstatus, siginfo_t *si)
{
int pid;
- int wait_errno;
int status;
struct tcb *tcp;
struct rusage ru;
return TE_BREAK;
}
- if (interactive)
- sigprocmask(SIG_SETMASK, &start_set, NULL);
pid = wait4(-1, pstatus, __WALL, (cflag ? &ru : NULL));
- wait_errno = errno;
- if (interactive)
- sigprocmask(SIG_SETMASK, &blocked_set, NULL);
-
if (pid < 0) {
- if (wait_errno == EINTR)
+ if (errno == EINTR)
return TE_NEXT;
- if (nprocs == 0 && wait_errno == ECHILD)
+ if (nprocs == 0 && errno == ECHILD)
return TE_BREAK;
/*
* If nprocs > 0, ECHILD is not expected,
* treat it as any other error here:
*/
- errno = wait_errno;
perror_msg_and_die("wait4(__WALL)");
}