faulthandler: Restore the old sigaltstack during teardown (GH-777) (GH-797)
(cherry picked from commit 20fbf8accd494fd15b0fc4c84928178c71ead4d1)
diff --git a/Modules/faulthandler.c b/Modules/faulthandler.c
index 1c1e4fb..2f8b624 100644
--- a/Modules/faulthandler.c
+++ b/Modules/faulthandler.c
@@ -124,6 +124,7 @@
#ifdef HAVE_SIGALTSTACK
static stack_t stack;
+static stack_t old_stack;
#endif
@@ -1310,7 +1311,7 @@
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;
@@ -1366,6 +1367,20 @@
faulthandler_disable();
#ifdef HAVE_SIGALTSTACK
if (stack.ss_sp != NULL) {
+ /* Fetch the current alt stack */
+ stack_t current_stack;
+ if (sigaltstack(NULL, ¤t_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;
}