From: Dmitry V. Levin Date: Fri, 23 Mar 2018 00:20:33 +0000 (+0000) Subject: strace: rewrite restart error handling without sigsetjmp/siglongjmp X-Git-Tag: v4.22~61 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=f56a3feb32d1c4a8d8da58bdd46446e431331c51;p=strace strace: rewrite restart error handling without sigsetjmp/siglongjmp Further simplify and optimize error handling of the delay signal handler by replacing sigsetjmp/siglongjmp mechanism with an error flag. * strace.c: Do not include . (restart_failed): New volatile variable. (timer_jmp_buf): Remove. (next_event): Cache is_delay_timer_created() return value, remove sigsetjmp invocation, check restart_failed instead. (timer_sighandler): Replace siglongjmp with setting restart_failed. --- diff --git a/strace.c b/strace.c index 173fdab7..16b1a864 100644 --- a/strace.c +++ b/strace.c @@ -34,7 +34,6 @@ #include #include #include "ptrace.h" -#include #include #include #include @@ -168,12 +167,11 @@ static void cleanup(void); static void interrupt(int sig); #ifdef HAVE_SIG_ATOMIC_T -static volatile sig_atomic_t interrupted; +static volatile sig_atomic_t interrupted, restart_failed; #else -static volatile int interrupted; +static volatile int interrupted, restart_failed; #endif -static jmp_buf timer_jmp_buf; static sigset_t timer_set; static void timer_sighandler(int); @@ -2238,6 +2236,8 @@ next_event(int *pstatus, siginfo_t *si) return TE_BREAK; } + const bool unblock_delay_timer = is_delay_timer_created(); + /* * The window of opportunity to handle expirations * of the delay timer opens here. @@ -2245,16 +2245,8 @@ next_event(int *pstatus, siginfo_t *si) * Unblock the signal handler for the delay timer * iff the delay timer is already created. */ - if (is_delay_timer_created()) { - if (sigsetjmp(timer_jmp_buf, 1)) { - /* - * restart_delayed_tcbs() forwarded an error - * from dispatch_event(). - */ - return TE_BREAK; - } + if (unblock_delay_timer) sigprocmask(SIG_UNBLOCK, &timer_set, NULL); - } /* * If the delay timer has expired, then its expiration @@ -2272,11 +2264,15 @@ next_event(int *pstatus, siginfo_t *si) * of the delay timer closes here. * * Block the signal handler for the delay timer - * iff the delay timer is already created. + * iff it was unblocked earlier. */ - if (is_delay_timer_created()) + if (unblock_delay_timer) { sigprocmask(SIG_BLOCK, &timer_set, NULL); + if (restart_failed) + return TE_BREAK; + } + if (pid < 0) { if (wait_errno == EINTR) return TE_NEXT; @@ -2611,10 +2607,13 @@ restart_delayed_tcbs(void) static void timer_sighandler(int sig) { + if (restart_failed) + return; + int saved_errno = errno; if (!restart_delayed_tcbs()) - siglongjmp(timer_jmp_buf, 1); + restart_failed = 1; errno = saved_errno; }