diff options
author | Dave Watson <davejwatson@fb.com> | 2016-11-30 11:40:20 -0800 |
---|---|---|
committer | Dave Watson <davejwatson@fb.com> | 2017-01-13 08:28:22 -0800 |
commit | 29483327bebaf6e0141a9bee8bb99552a63f1583 (patch) | |
tree | 7ed9ec739cb062f5c563544f7d23b55f2d8238e5 /tests | |
parent | b707e13ca0db5c40cd6cb50634241fd417afa8d1 (diff) | |
download | libunwind-29483327bebaf6e0141a9bee8bb99552a63f1583.tar.gz |
x86_64: Use sigprocmask from signal frames
Currently setcontext for x86_64 restores the signal mask, even
though it is never saved anywhere. This means the signal mask
is often garbage after an unw_resume.
(changed in commit f8a15e9679e59872ca2)
It looks like this was a fix for the Gtest-resume-sig function -
testing if signal masks are restored across signal frames. The
root issue looks like that x86_64 only uses sigreturn for the exact
signal frame, and not for any decedant frames as well (as i64 does).
Instead, modify Gresume to use sigreturn if *any* frame on the stack
is a signal frame, so that we correct fixup the signal mask and any
sigaltstacks. The sigreturn os-specific functions are changed slightly
to copy in the saved ucontext structure if we are jumping farther
up the stack.
This should fix sigprocmask reported issues such as
https://github.com/dropbox/pyston/blob/master/libunwind_patches/0002-pyston-stop-x86_64-setcontext-restoring-uninitialize.patch
Tests pass on freebsd, linux
Diffstat (limited to 'tests')
-rw-r--r-- | tests/Gtest-resume-sig.c | 8 |
1 files changed, 2 insertions, 6 deletions
diff --git a/tests/Gtest-resume-sig.c b/tests/Gtest-resume-sig.c index 147ecd03..846bba9f 100644 --- a/tests/Gtest-resume-sig.c +++ b/tests/Gtest-resume-sig.c @@ -74,7 +74,7 @@ handler (int sig) #endif { unw_word_t ip; - sigset_t mask, oldmask; + sigset_t mask; unw_context_t uc; unw_cursor_t c; char foo; @@ -95,17 +95,13 @@ handler (int sig) sigemptyset (&mask); sigaddset (&mask, SIGUSR2); - sigprocmask (SIG_BLOCK, &mask, &oldmask); + sigprocmask (SIG_BLOCK, &mask, NULL); kill (getpid (), SIGUSR2); /* pend SIGUSR2 */ signal (SIGUSR1, SIG_IGN); if ((ret = unw_getcontext (&uc)) < 0) panic ("unw_getcontext() failed: ret=%d\n", ret); -#if UNW_TARGET_X86_64 - /* unw_getcontext() doesn't save signal mask to avoid a syscall */ - uc.uc_sigmask = oldmask; -#endif if ((ret = unw_init_local (&c, &uc)) < 0) panic ("unw_init_local() failed: ret=%d\n", ret); |