diff --git a/js/src/jsnativestack.cpp b/js/src/jsnativestack.cpp index 29cc77f4591..9fec01d35f0 100644 --- a/js/src/jsnativestack.cpp +++ b/js/src/jsnativestack.cpp @@ -23,6 +23,11 @@ # include # endif +# if defined(ANDROID) +# include +# include +# endif + #else # error "Unsupported platform" @@ -125,17 +130,43 @@ js::GetNativeStackBaseImpl() 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);