]> granicus.if.org Git - python/commitdiff
faulthandler: Restore the old sigaltstack during teardown (GH-777) (GH-796)
authorChristophe Zeitouny <tich@users.noreply.github.com>
Fri, 24 Mar 2017 11:21:37 +0000 (04:21 -0700)
committerMariatta <Mariatta@users.noreply.github.com>
Fri, 24 Mar 2017 11:21:37 +0000 (04:21 -0700)
(cherry picked from commit 20fbf8accd494fd15b0fc4c84928178c71ead4d1)

Misc/ACKS
Misc/NEWS
Modules/faulthandler.c

index 8a952a45f5dcd41e7bf4090efca05056738a0fcc..edfbb448bd91551b1d303801dfa14eb511c44373 100644 (file)
--- a/Misc/ACKS
+++ b/Misc/ACKS
@@ -1679,6 +1679,7 @@ Artur Zaprzala
 Mike Zarnstorff
 Yury V. Zaytsev
 Siebren van der Zee
+Christophe Zeitouny
 Nickolai Zeldovich
 Yuxiao Zeng
 Uwe Zessin
index e45cf3edfdaf8a881bb64b92554f3da6177093aa..e063455b986413657578825b9245f3e5a2a9ec9a 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -46,6 +46,9 @@ Extension Modules
 Library
 -------
 
+- bpo-29884: faulthandler: Restore the old sigaltstack during teardown.
+  Patch by Christophe Zeitouny.
+
 - bpo-25455: Fixed crashes in repr of recursive buffered file-like objects.
 
 - bpo-29800: Fix crashes in partial.__repr__ if the keys of partial.keywords
index f1fda481fc61bf6548448985c6d57943adb0c654..56285b6358e0560f0f37291bb093168f3b15594b 100644 (file)
@@ -124,6 +124,7 @@ static const unsigned char faulthandler_nsignals = \
 
 #ifdef HAVE_SIGALTSTACK
 static stack_t stack;
+static stack_t old_stack;
 #endif
 
 
@@ -1148,7 +1149,7 @@ int _PyFaulthandler_Init(void)
     stack.ss_size = SIGSTKSZ;
     stack.ss_sp = PyMem_Malloc(stack.ss_size);
     if (stack.ss_sp != NULL) {
-        err = sigaltstack(&stack, NULL);
+        err = sigaltstack(&stack, &old_stack);
         if (err) {
             PyMem_Free(stack.ss_sp);
             stack.ss_sp = NULL;
@@ -1204,6 +1205,20 @@ void _PyFaulthandler_Fini(void)
     faulthandler_disable();
 #ifdef HAVE_SIGALTSTACK
     if (stack.ss_sp != NULL) {
+        /* Fetch the current alt stack */
+        stack_t current_stack;
+        if (sigaltstack(NULL, &current_stack) == 0) {
+            if (current_stack.ss_sp == stack.ss_sp) {
+                /* The current alt stack is the one that we installed.
+                 It is safe to restore the old stack that we found when
+                 we installed ours */
+                sigaltstack(&old_stack, NULL);
+            } else {
+                /* Someone switched to a different alt stack and didn't
+                   restore ours when they were done (if they're done).
+                   There's not much we can do in this unlikely case */
+            }
+        }
         PyMem_Free(stack.ss_sp);
         stack.ss_sp = NULL;
     }