Clean up our alternate signal stacks.
Bug: 8557703
Change-Id: Ie93901dd1c29e9d3bf795b0f0400616d9ef08f75
diff --git a/libc/bionic/pthread.c b/libc/bionic/pthread.c
index 8589cd6..92e2c27 100644
--- a/libc/bionic/pthread.c
+++ b/libc/bionic/pthread.c
@@ -31,6 +31,7 @@
#include <errno.h>
#include <limits.h>
#include <sys/atomics.h>
+#include <sys/mman.h>
#include <unistd.h>
#include "bionic_atomic_inline.h"
@@ -102,6 +103,18 @@
// space (see pthread_key_delete)
pthread_key_clean_all();
+ if (thread->alternate_signal_stack != NULL) {
+ // Tell the kernel to stop using the alternate signal stack.
+ stack_t ss;
+ ss.ss_sp = NULL;
+ ss.ss_flags = SS_DISABLE;
+ sigaltstack(&ss, NULL);
+
+ // Free it.
+ munmap(thread->alternate_signal_stack, SIGSTKSZ);
+ thread->alternate_signal_stack = NULL;
+ }
+
// if the thread is detached, destroy the pthread_internal_t
// otherwise, keep it in memory and signal any joiners.
pthread_mutex_lock(&gThreadListLock);
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 5908a1b..d38e20c 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -69,6 +69,7 @@
ss.ss_size = SIGSTKSZ;
ss.ss_flags = 0;
sigaltstack(&ss, NULL);
+ thread->alternate_signal_stack = ss.ss_sp;
}
// Slot 0 must point to itself. The x86 Linux kernel reads the TLS from %fs:0.
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index e34788b..98199d3 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -47,6 +47,8 @@
__pthread_cleanup_t* cleanup_stack;
void** tls; /* thread-local storage area */
+ void* alternate_signal_stack;
+
/*
* The dynamic linker implements dlerror(3), which makes it hard for us to implement this
* per-thread buffer by simply using malloc(3) and free(3).