]> Gitweb @ Texas Instruments - Open Source Git Repositories - git.TI.com/gitweb - android-sdk/platform-bionic.git/commitdiff
Merge "Fix pthread_getattr_np for the main thread."
authorElliott Hughes <enh@google.com>
Tue, 26 Aug 2014 19:53:40 +0000 (19:53 +0000)
committerGerrit Code Review <noreply-gerritcodereview@google.com>
Tue, 26 Aug 2014 19:53:40 +0000 (19:53 +0000)
16 files changed:
libc/arch-arm/arm.mk
libc/arch-arm/bionic/__get_sp.S [deleted file]
libc/arch-arm64/arm64.mk
libc/arch-arm64/bionic/__get_sp.S [deleted file]
libc/arch-mips/bionic/__get_sp.S [deleted file]
libc/arch-mips/mips.mk
libc/arch-mips64/bionic/__get_sp.S [deleted file]
libc/arch-x86/bionic/__get_sp.S [deleted file]
libc/arch-x86/x86.mk
libc/arch-x86_64/bionic/__get_sp.S [deleted file]
libc/arch-x86_64/x86_64.mk
libc/bionic/libc_init_common.cpp
libc/bionic/pthread_attr.cpp
libc/private/bionic_string_utils.h [new file with mode: 0644]
tests/dlfcn_test.cpp
tests/pthread_test.cpp

index 00be4aed54583b4158a10ee4b2c81898e6e12b5d..70cc8eba66e2ada8d8f119dd8550680732bd7dfe 100644 (file)
@@ -53,7 +53,6 @@ libc_bionic_src_files_arm += \
     arch-arm/bionic/atomics_arm.c \
     arch-arm/bionic/__bionic_clone.S \
     arch-arm/bionic/_exit_with_stack_teardown.S \
-    arch-arm/bionic/__get_sp.S \
     arch-arm/bionic/libgcc_compat.c \
     arch-arm/bionic/memcmp.S \
     arch-arm/bionic/_setjmp.S \
diff --git a/libc/arch-arm/bionic/__get_sp.S b/libc/arch-arm/bionic/__get_sp.S
deleted file mode 100644 (file)
index 9ae6f24..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <private/bionic_asm.h>
-
-ENTRY_PRIVATE(__get_sp)
-  mov r0, sp
-  bx lr
-END(__get_sp)
index ed991ce603dc4c0fe529fea4f4e1022a8afa1142..6c4f6a6e8726fca694c3c14ff1e9dc9b4811b6cf 100644 (file)
@@ -29,7 +29,6 @@ libc_common_src_files_arm64 += \
 libc_bionic_src_files_arm64 := \
     arch-arm64/bionic/__bionic_clone.S \
     arch-arm64/bionic/_exit_with_stack_teardown.S \
-    arch-arm64/bionic/__get_sp.S \
     arch-arm64/bionic/__rt_sigreturn.S \
     arch-arm64/bionic/_setjmp.S \
     arch-arm64/bionic/setjmp.S \
diff --git a/libc/arch-arm64/bionic/__get_sp.S b/libc/arch-arm64/bionic/__get_sp.S
deleted file mode 100644 (file)
index d5e88e9..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <private/bionic_asm.h>
-
-ENTRY_PRIVATE(__get_sp)
-    mov x0, sp
-    ret
-END(__get_sp)
diff --git a/libc/arch-mips/bionic/__get_sp.S b/libc/arch-mips/bionic/__get_sp.S
deleted file mode 100644 (file)
index 5f5d32e..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <private/bionic_asm.h>
-
-ENTRY_PRIVATE(__get_sp)
-  move v0, sp
-  j ra
-END(__get_sp)
index 8e415f9570ec7f8aa8b4a6f9fca1aa9126d3f7c7..31a1f32fd99a1bf7b8f53236eb24af055124f284 100644 (file)
@@ -54,7 +54,6 @@ libc_bionic_src_files_mips += \
     arch-mips/bionic/bzero.S \
     arch-mips/bionic/cacheflush.cpp \
     arch-mips/bionic/_exit_with_stack_teardown.S \
-    arch-mips/bionic/__get_sp.S \
     arch-mips/bionic/_setjmp.S \
     arch-mips/bionic/setjmp.S \
     arch-mips/bionic/sigsetjmp.S \
diff --git a/libc/arch-mips64/bionic/__get_sp.S b/libc/arch-mips64/bionic/__get_sp.S
deleted file mode 100644 (file)
index 5f5d32e..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <private/bionic_asm.h>
-
-ENTRY_PRIVATE(__get_sp)
-  move v0, sp
-  j ra
-END(__get_sp)
diff --git a/libc/arch-x86/bionic/__get_sp.S b/libc/arch-x86/bionic/__get_sp.S
deleted file mode 100644 (file)
index aea6ac6..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2008 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <private/bionic_asm.h>
-
-ENTRY_PRIVATE(__get_sp)
-  mov  %esp, %eax
-  ret
-END(__get_sp)
index 019dc8e813ce3c52e96229fda5b277c6741418eb..a14154866b4090077243248dd66a969c66befe1b 100644 (file)
@@ -25,7 +25,6 @@ libc_bionic_src_files_x86 := \
 libc_bionic_src_files_x86 += \
     arch-x86/bionic/__bionic_clone.S \
     arch-x86/bionic/_exit_with_stack_teardown.S \
-    arch-x86/bionic/__get_sp.S \
     arch-x86/bionic/_setjmp.S \
     arch-x86/bionic/setjmp.S \
     arch-x86/bionic/__set_tls.c \
diff --git a/libc/arch-x86_64/bionic/__get_sp.S b/libc/arch-x86_64/bionic/__get_sp.S
deleted file mode 100644 (file)
index 49a2406..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <private/bionic_asm.h>
-
-ENTRY_PRIVATE(__get_sp)
-  mov  %rsp, %rax
-  ret
-END(__get_sp)
index 7887c519e7614f804860ddfa2fd4351717b6c3ad..b001b5e98a47dd5a5cd6a3026804f637a0d8562d 100644 (file)
@@ -30,7 +30,6 @@ libc_common_src_files_x86_64 += \
 libc_bionic_src_files_x86_64 := \
     arch-x86_64/bionic/__bionic_clone.S \
     arch-x86_64/bionic/_exit_with_stack_teardown.S \
-    arch-x86_64/bionic/__get_sp.S \
     arch-x86_64/bionic/__rt_sigreturn.S \
     arch-x86_64/bionic/_setjmp.S \
     arch-x86_64/bionic/setjmp.S \
index ff9940ef76ea7f3330e6d71505679f53f30fd893..2a6a03b5d688462c520c2adbff3a49d064c2c6dc 100644 (file)
@@ -36,7 +36,6 @@
 #include <stdlib.h>
 #include <sys/auxv.h>
 #include <sys/time.h>
-#include <sys/resource.h>
 #include <unistd.h>
 
 #include "private/bionic_auxv.h"
@@ -46,7 +45,6 @@
 #include "pthread_internal.h"
 
 extern "C" abort_msg_t** __abort_message_ptr;
-extern "C" uintptr_t __get_sp(void);
 extern "C" int __system_properties_init(void);
 extern "C" int __set_tls(void* ptr);
 extern "C" int __set_tid_address(int* tid_address);
@@ -62,17 +60,6 @@ char** environ;
 // Declared in "private/bionic_ssp.h".
 uintptr_t __stack_chk_guard = 0;
 
-static size_t get_main_thread_stack_size() {
-  rlimit stack_limit;
-  int rlimit_result = getrlimit(RLIMIT_STACK, &stack_limit);
-  if ((rlimit_result == 0) &&
-      (stack_limit.rlim_cur != RLIM_INFINITY) &&
-      (stack_limit.rlim_cur > PTHREAD_STACK_MIN)) {
-    return (stack_limit.rlim_cur & ~(PAGE_SIZE - 1));
-  }
-  return PTHREAD_STACK_SIZE_DEFAULT;
-}
-
 /* Init TLS for the initial thread. Called by the linker _before_ libc is mapped
  * in memory. Beware: all writes to libc globals from this function will
  * apply to linker-private copies and will not be visible from libc later on.
@@ -96,16 +83,15 @@ void __libc_init_tls(KernelArgumentBlock& args) {
   main_thread.tid = __set_tid_address(&main_thread.tid);
   main_thread.set_cached_pid(main_thread.tid);
 
-  // Work out the extent of the main thread's stack.
-  uintptr_t stack_top = (__get_sp() & ~(PAGE_SIZE - 1)) + PAGE_SIZE;
-  size_t stack_size = get_main_thread_stack_size();
-  void* stack_bottom = reinterpret_cast<void*>(stack_top - stack_size);
-
   // We don't want to free the main thread's stack even when the main thread exits
   // because things like environment variables with global scope live on it.
+  // We also can't free the pthread_internal_t itself, since that lives on the main
+  // thread's stack rather than on the heap.
   pthread_attr_init(&main_thread.attr);
-  pthread_attr_setstack(&main_thread.attr, stack_bottom, stack_size);
   main_thread.attr.flags = PTHREAD_ATTR_FLAG_USER_ALLOCATED_STACK | PTHREAD_ATTR_FLAG_MAIN_THREAD;
+  main_thread.attr.guard_size = 0; // The main thread has no guard page.
+  main_thread.attr.stack_size = 0; // User code should never see this; we'll compute it when asked.
+  // TODO: the main thread's sched_policy and sched_priority need to be queried.
 
   __init_thread(&main_thread, false);
   __init_tls(&main_thread);
index e1cd85365bcde711c70362018cc3563745a8d786..8df3bffacd112041b2f674825661e71cf5bca722 100644 (file)
 
 #include <pthread.h>
 
+#include <inttypes.h>
+#include <stdio.h>
+#include <sys/resource.h>
+
+#include "private/bionic_string_utils.h"
+#include "private/ErrnoRestorer.h"
+#include "private/libc_logging.h"
 #include "pthread_internal.h"
 
 int pthread_attr_init(pthread_attr_t* attr) {
@@ -90,8 +97,8 @@ int pthread_attr_setstacksize(pthread_attr_t* attr, size_t stack_size) {
 }
 
 int pthread_attr_getstacksize(const pthread_attr_t* attr, size_t* stack_size) {
-  *stack_size = attr->stack_size;
-  return 0;
+  void* unused;
+  return pthread_attr_getstack(attr, &unused, stack_size);
 }
 
 int pthread_attr_setstack(pthread_attr_t* attr, void* stack_base, size_t stack_size) {
@@ -106,7 +113,42 @@ int pthread_attr_setstack(pthread_attr_t* attr, void* stack_base, size_t stack_s
   return 0;
 }
 
+static int __pthread_attr_getstack_main_thread(void** stack_base, size_t* stack_size) {
+  ErrnoRestorer errno_restorer;
+
+  // It doesn't matter which thread we are; we're just looking for "[stack]".
+  FILE* fp = fopen("/proc/self/maps", "re");
+  if (fp == NULL) {
+    return errno;
+  }
+  char line[BUFSIZ];
+  while (fgets(line, sizeof(line), fp) != NULL) {
+    if (ends_with(line, " [stack]\n")) {
+      uintptr_t lo, hi;
+      if (sscanf(line, "%" SCNxPTR "-%" SCNxPTR, &lo, &hi) == 2) {
+        *stack_base = reinterpret_cast<void*>(lo);
+        *stack_size = hi - lo;
+
+        // Does our current RLIMIT_STACK mean we won't actually get everything /proc/maps promises?
+        rlimit stack_limit;
+        if (getrlimit(RLIMIT_STACK, &stack_limit) != -1) {
+          if (*stack_size > stack_limit.rlim_cur) {
+            *stack_size = stack_limit.rlim_cur;
+          }
+        }
+
+        fclose(fp);
+        return 0;
+      }
+    }
+  }
+  __libc_fatal("No [stack] line found in /proc/self/maps!");
+}
+
 int pthread_attr_getstack(const pthread_attr_t* attr, void** stack_base, size_t* stack_size) {
+  if ((attr->flags & PTHREAD_ATTR_FLAG_MAIN_THREAD) != 0) {
+    return __pthread_attr_getstack_main_thread(stack_base, stack_size);
+  }
   *stack_base = attr->stack_base;
   *stack_size = attr->stack_size;
   return 0;
@@ -122,9 +164,8 @@ int pthread_attr_getguardsize(const pthread_attr_t* attr, size_t* guard_size) {
   return 0;
 }
 
-int pthread_getattr_np(pthread_t thid, pthread_attr_t* attr) {
-  pthread_internal_t* thread = (pthread_internal_t*) thid;
-  *attr = thread->attr;
+int pthread_getattr_np(pthread_t t, pthread_attr_t* attr) {
+  *attr = reinterpret_cast<pthread_internal_t*>(t)->attr;
   return 0;
 }
 
diff --git a/libc/private/bionic_string_utils.h b/libc/private/bionic_string_utils.h
new file mode 100644 (file)
index 0000000..ab0eccf
--- /dev/null
@@ -0,0 +1,31 @@
+/*
+ * Copyright (C) 2014 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef _BIONIC_STRING_UTILS_H_
+#define _BIONIC_STRING_UTILS_H_
+
+#include <string.h>
+
+static inline bool ends_with(const char* s1, const char* s2) {
+  size_t s1_length = strlen(s1);
+  size_t s2_length = strlen(s2);
+  if (s2_length > s1_length) {
+    return false;
+  }
+  return memcmp(s1 + (s1_length - s2_length), s2, s2_length) == 0;
+}
+
+#endif // _BIONIC_STRING_UTILS_H_
index a731748551587eda6a218aca49de67a66747ff5b..6de38c89e25f419e2b9c985e6d0f446597cbd6c7 100644 (file)
@@ -231,10 +231,8 @@ TEST(dlfcn, dladdr) {
   // Look in /proc/pid/maps to find out what address we were loaded at.
   // TODO: factor /proc/pid/maps parsing out into a class and reuse all over bionic.
   void* base_address = NULL;
-  char path[PATH_MAX];
-  snprintf(path, sizeof(path), "/proc/%d/maps", getpid());
   char line[BUFSIZ];
-  FILE* fp = fopen(path, "r");
+  FILE* fp = fopen("/proc/self/maps", "r");
   ASSERT_TRUE(fp != NULL);
   while (fgets(line, sizeof(line), fp) != NULL) {
     uintptr_t start = strtoul(line, 0, 16);
index 5328e48cffa6452599bf8f4140304e1e2b74aa55..5f74e388d6c8345106f2a3693ba210cab02dc0af 100644 (file)
@@ -23,6 +23,7 @@
 #include <pthread.h>
 #include <signal.h>
 #include <sys/mman.h>
+#include <sys/syscall.h>
 #include <time.h>
 #include <unistd.h>
 
@@ -816,3 +817,88 @@ TEST(pthread, pthread_mutex_timedlock) {
   ASSERT_EQ(0, pthread_mutex_unlock(&m));
   ASSERT_EQ(0, pthread_mutex_destroy(&m));
 }
+
+TEST(pthread, pthread_attr_getstack__main_thread) {
+  // This test is only meaningful for the main thread, so make sure we're running on it!
+  ASSERT_EQ(getpid(), syscall(__NR_gettid));
+
+  // Get the main thread's attributes.
+  pthread_attr_t attributes;
+  ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attributes));
+
+  // Check that we correctly report that the main thread has no guard page.
+  size_t guard_size;
+  ASSERT_EQ(0, pthread_attr_getguardsize(&attributes, &guard_size));
+  ASSERT_EQ(0U, guard_size); // The main thread has no guard page.
+
+  // Get the stack base and the stack size (both ways).
+  void* stack_base;
+  size_t stack_size;
+  ASSERT_EQ(0, pthread_attr_getstack(&attributes, &stack_base, &stack_size));
+  size_t stack_size2;
+  ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size2));
+
+  // The two methods of asking for the stack size should agree.
+  EXPECT_EQ(stack_size, stack_size2);
+
+  // What does /proc/self/maps' [stack] line say?
+  void* maps_stack_base = NULL;
+  size_t maps_stack_size = 0;
+  FILE* fp = fopen("/proc/self/maps", "r");
+  ASSERT_TRUE(fp != NULL);
+  char line[BUFSIZ];
+  while (fgets(line, sizeof(line), fp) != NULL) {
+    uintptr_t lo, hi;
+    char name[10];
+    sscanf(line, "%" PRIxPTR "-%" PRIxPTR " %*4s %*x %*x:%*x %*d %10s", &lo, &hi, name);
+    if (strcmp(name, "[stack]") == 0) {
+      maps_stack_base = reinterpret_cast<void*>(lo);
+      maps_stack_size = hi - lo;
+      break;
+    }
+  }
+  fclose(fp);
+
+#if defined(__BIONIC__)
+  // bionic thinks that the stack base and size should correspond to the mapped region.
+  EXPECT_EQ(maps_stack_base, stack_base);
+  EXPECT_EQ(maps_stack_size, stack_size);
+#else
+  // glibc doesn't give the true extent for some reason.
+#endif
+
+  // Both bionic and glibc agree that the high address you can compute from the returned
+  // values should match what /proc/self/maps says.
+  void* stack_end = reinterpret_cast<uint8_t*>(stack_base) + stack_size;
+  void* maps_stack_end = reinterpret_cast<uint8_t*>(maps_stack_base) + maps_stack_size;
+  EXPECT_EQ(maps_stack_end, stack_end);
+
+  //
+  // What if the rlimit is smaller than the stack's current extent?
+  //
+  rlimit rl;
+  rl.rlim_cur = rl.rlim_max = 1024; // 1KiB. We know the stack must be at least a page already.
+  rl.rlim_max = RLIM_INFINITY;
+  ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
+
+  ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attributes));
+  ASSERT_EQ(0, pthread_attr_getstack(&attributes, &stack_base, &stack_size));
+  ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size2));
+
+  EXPECT_EQ(stack_size, stack_size2);
+  ASSERT_EQ(1024U, stack_size);
+
+  //
+  // What if the rlimit isn't a whole number of pages?
+  //
+  rl.rlim_cur = rl.rlim_max = 6666; // Not a whole number of pages.
+  rl.rlim_max = RLIM_INFINITY;
+  ASSERT_EQ(0, setrlimit(RLIMIT_STACK, &rl));
+
+  ASSERT_EQ(0, pthread_getattr_np(pthread_self(), &attributes));
+  ASSERT_EQ(0, pthread_attr_getstack(&attributes, &stack_base, &stack_size));
+  ASSERT_EQ(0, pthread_attr_getstacksize(&attributes, &stack_size2));
+
+  EXPECT_EQ(stack_size, stack_size2);
+  ASSERT_EQ(6666U, stack_size);
+}