summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorDave Watson <davejwatson@fb.com>2016-11-30 11:40:20 -0800
committerDave Watson <davejwatson@fb.com>2017-01-13 08:28:22 -0800
commit29483327bebaf6e0141a9bee8bb99552a63f1583 (patch)
tree7ed9ec739cb062f5c563544f7d23b55f2d8238e5 /tests
parentb707e13ca0db5c40cd6cb50634241fd417afa8d1 (diff)
downloadlibunwind-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.c8
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);