Bug 846670 - Initialize stackBase and stackSize properly for the main-thread when using bionic. r=billm
authorDave Hylands <dhylands@mozilla.com>
Wed, 13 Mar 2013 16:31:15 -0700
changeset 124833 8b3c093d11eb8ec44353ae1ba4fecb24e2d743e8
parent 124832 7d2ea731f5a5309583451dc519c6bedb1e692ddd
child 124834 2626965bcf333f15f9c30c3836cf4b0477593961
push id24436
push userryanvm@gmail.com
push dateFri, 15 Mar 2013 11:52:55 +0000
treeherdermozilla-central@8f5b1f9f5804 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbillm
bugs846670
milestone22.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 846670 - Initialize stackBase and stackSize properly for the main-thread when using bionic. r=billm
js/src/jsnativestack.cpp
--- a/js/src/jsnativestack.cpp
+++ b/js/src/jsnativestack.cpp
@@ -18,16 +18,21 @@
 
 #elif defined(XP_MACOSX) || defined(DARWIN) || defined(XP_UNIX)
 # include <pthread.h>
 
 # if defined(__FreeBSD__) || defined(__OpenBSD__)
 #  include <pthread_np.h>
 # endif
 
+# if defined(ANDROID)
+#  include <unistd.h>
+#  include <sys/types.h>
+# endif
+
 #else
 # error "Unsupported platform"
 
 #endif
 
 #if defined(XP_WIN)
 
 void *
@@ -120,27 +125,53 @@ js::GetNativeStackBaseImpl()
      * FIXME: this function is non-portable;
      * other POSIX systems may have different np alternatives
      */
     pthread_getattr_np(thread, &sattr);
 #  endif
 
     void *stackBase = 0;
     size_t stackSize = 0;
-#  ifdef DEBUG
-    int rc =
-#  endif
+    int rc;
 # if defined(__OpenBSD__)
-        pthread_stackseg_np(pthread_self(), &ss);
+    rc = pthread_stackseg_np(pthread_self(), &ss);
     stackBase = (void*)((size_t) ss.ss_sp - ss.ss_size);
     stackSize = ss.ss_size;
+# elif defined(ANDROID)
+    if (gettid() == getpid()) {
+        // bionic's pthread_attr_getstack doesn't tell the truth for the main
+        // thread (see bug 846670). So we scan /proc/self/maps to find the
+        // segment which contains the stack.
+        rc = -1;
+        FILE *fs = fopen("/proc/self/maps", "r");
+        if (fs) {
+            char line[100];
+            unsigned long stackAddr = (unsigned long)&sattr;
+            while (fgets(line, sizeof(line), fs) != NULL) {
+                unsigned long stackStart;
+                unsigned long stackEnd;
+                if (sscanf(line, "%lx-%lx ", &stackStart, &stackEnd) == 2 &&
+                    stackAddr >= stackStart && stackAddr < stackEnd) {
+                    stackBase = (void *)stackStart;
+                    stackSize = stackEnd - stackStart;
+                    rc = 0;
+                    break;
+                }
+            }
+            fclose(fs);
+        }
+    } else
+        // For non main-threads pthread allocates the stack itself so it tells
+        // the truth.
+        rc = pthread_attr_getstack(&sattr, &stackBase, &stackSize);
 # else
-        pthread_attr_getstack(&sattr, &stackBase, &stackSize);
+    rc = pthread_attr_getstack(&sattr, &stackBase, &stackSize);
 # endif
-    JS_ASSERT(!rc);
+    if (rc)
+        MOZ_CRASH();
     JS_ASSERT(stackBase);
     pthread_attr_destroy(&sattr);
 
 #  if JS_STACK_GROWTH_DIRECTION > 0
     return stackBase;
 #  else
     return static_cast<char*>(stackBase) + stackSize;
 #  endif