summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorElliott Hughes <enh@google.com>2013-03-29 16:37:25 -0700
committerElliott Hughes <enh@google.com>2013-03-29 17:00:30 -0700
commit91b8b139893877cca509f35afa0075713d2ff7f3 (patch)
tree26dcf612df4f730b2eb53cb627c26e8ebd54354a
parent4d5b4344904b099ea60b770df61d4e19bf23ecf1 (diff)
downloaddalvik-91b8b139893877cca509f35afa0075713d2ff7f3.tar.gz
Extra log information when pthread_create fails.
Bug: 8470684 (cherry picked from commit 3eeda5e6fe172758e47d237694daf4f9421f3c12) Change-Id: Ideba410d393b69753bbfae7558a2692edd08d339
-rw-r--r--vm/Thread.cpp56
1 files changed, 45 insertions, 11 deletions
diff --git a/vm/Thread.cpp b/vm/Thread.cpp
index ded6f0f1f..5ca055fe0 100644
--- a/vm/Thread.cpp
+++ b/vm/Thread.cpp
@@ -27,13 +27,10 @@
#include <sys/resource.h>
#include <sys/mman.h>
#include <signal.h>
+#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
-#ifdef HAVE_ANDROID_OS
-#include <dirent.h>
-#endif
-
#if defined(HAVE_PRCTL)
#include <sys/prctl.h>
#endif
@@ -1311,13 +1308,53 @@ bool dvmCreateInterpThread(Object* threadObj, int reqStackSize)
* resource limits. VirtualMachineError is probably too severe,
* so use OutOfMemoryError.
*/
- ALOGE("pthread_create (stack size %d bytes) failed: %s", stackSize, strerror(cc));
+
+#if HAVE_ANDROID_OS
+ struct mallinfo malloc_info;
+ malloc_info = mallinfo();
+ ALOGE("Native heap free: %zd of %zd bytes", malloc_info.fordblks, malloc_info.uordblks);
+#endif
+
+ size_t thread_count = 0;
+ DIR* d = opendir("/proc/self/task");
+ if (d != NULL) {
+ dirent* entry = NULL;
+ while ((entry = readdir(d)) != NULL) {
+ char* end;
+ strtol(entry->d_name, &end, 10);
+ if (!*end) {
+ ++thread_count;
+ }
+ }
+ closedir(d);
+ }
+
+ ALOGE("pthread_create (%d threads) failed: %s", thread_count, strerror(cc));
+
+ // Super-verbose output to help track down http://b/8470684.
+ size_t map_count = 0;
+ FILE* fp = fopen("/proc/self/maps", "r");
+ if (fp != NULL) {
+ char buf[1024];
+ while (fgets(buf, sizeof(buf), fp) != NULL) {
+ ALOGE("/proc/self/maps: %s", buf);
+ ++map_count;
+ }
+ fclose(fp);
+ }
dvmSetFieldObject(threadObj, gDvm.offJavaLangThread_vmThread, NULL);
dvmThrowExceptionFmt(gDvm.exOutOfMemoryError,
- "pthread_create (stack size %d bytes) failed: %s",
- stackSize, strerror(cc));
+ "pthread_create (%d threads, %d map entries, "
+#if HAVE_ANDROID_OS
+ "%zd free of %zd native heap bytes"
+#endif
+ ") failed: %s", thread_count, map_count,
+#if HAVE_ANDROID_OS
+ malloc_info.fordblks, malloc_info.uordblks,
+#endif
+ strerror(cc));
goto fail;
}
@@ -3490,10 +3527,7 @@ void dvmDumpAllThreadsEx(const DebugOutputTarget* target, bool grabLock)
}
#ifdef HAVE_ANDROID_OS
- char path[64];
- snprintf(path, sizeof(path), "/proc/%d/task", getpid());
-
- DIR* d = opendir(path);
+ DIR* d = opendir("/proc/self/task");
if (d != NULL) {
dirent* entry = NULL;
bool first = true;