OSDN Git Service

Clean up our alternate signal stacks.
authorElliott Hughes <enh@google.com>
Tue, 16 Jul 2013 21:32:47 +0000 (14:32 -0700)
committerElliott Hughes <enh@google.com>
Tue, 16 Jul 2013 21:35:52 +0000 (14:35 -0700)
Bug: 8557703
Change-Id: Ie93901dd1c29e9d3bf795b0f0400616d9ef08f75

libc/bionic/pthread.c
libc/bionic/pthread_create.cpp
libc/bionic/pthread_internal.h

index 8589cd6..92e2c27 100644 (file)
@@ -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 @@ void pthread_exit(void * retval)
     // 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);
index 5908a1b..d38e20c 100644 (file)
@@ -69,6 +69,7 @@ void  __init_tls(pthread_internal_t* thread) {
     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.
index e34788b..98199d3 100644 (file)
@@ -47,6 +47,8 @@ typedef struct pthread_internal_t
     __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).