diff options
author | Android (Google) Code Review <android-gerrit@google.com> | 2009-08-11 19:58:36 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2009-08-11 19:58:36 -0700 |
commit | b8546001701405a76dad7e6235046e592296fac2 (patch) | |
tree | 192f287fdc217bf11c616f2fae7a9b37d673ea1a | |
parent | 188f5a71061791906572de375c5efe26cadddbae (diff) | |
parent | 82e1ee93eece8fb0aec6acc3ef4ee7b1c86feec7 (diff) | |
download | frameworks_base-b8546001701405a76dad7e6235046e592296fac2.zip frameworks_base-b8546001701405a76dad7e6235046e592296fac2.tar.gz frameworks_base-b8546001701405a76dad7e6235046e592296fac2.tar.bz2 |
Merge change 20878 into donut
* changes:
Fix issue #2048263: More debugging information
-rw-r--r-- | core/java/android/app/ActivityThread.java | 8 | ||||
-rw-r--r-- | core/java/android/content/res/AssetManager.java | 5 | ||||
-rw-r--r-- | core/jni/android_util_AssetManager.cpp | 18 | ||||
-rw-r--r-- | include/utils/Asset.h | 12 | ||||
-rw-r--r-- | libs/utils/Asset.cpp | 58 | ||||
-rw-r--r-- | services/java/com/android/server/am/ActivityManagerService.java | 66 | ||||
-rw-r--r-- | services/java/com/android/server/am/HistoryRecord.java | 3 |
7 files changed, 157 insertions, 13 deletions
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java index 32a2891..e045105 100644 --- a/core/java/android/app/ActivityThread.java +++ b/core/java/android/app/ActivityThread.java @@ -1701,6 +1701,14 @@ public final class ActivityThread { printRow(pw, TWO_COUNT_COLUMNS, "numPagers:", stats.numPagers, "inactivePageKB:", (stats.totalBytes - stats.referencedBytes) / 1024); printRow(pw, ONE_COUNT_COLUMN, "activePageKB:", stats.referencedBytes / 1024); + + // Asset details. + String assetAlloc = AssetManager.getAssetAllocations(); + if (assetAlloc != null) { + pw.println(" "); + pw.println(" Asset Allocations"); + pw.print(assetAlloc); + } } private void printRow(PrintWriter pw, String format, Object...objs) { diff --git a/core/java/android/content/res/AssetManager.java b/core/java/android/content/res/AssetManager.java index 8ebe093..0bc8a9d 100644 --- a/core/java/android/content/res/AssetManager.java +++ b/core/java/android/content/res/AssetManager.java @@ -667,6 +667,11 @@ public final class AssetManager { /** * {@hide} */ + public native static final String getAssetAllocations(); + + /** + * {@hide} + */ public native static final int getGlobalAssetManagerCount(); private native final int newTheme(); diff --git a/core/jni/android_util_AssetManager.cpp b/core/jni/android_util_AssetManager.cpp index 66b2506..562cc8f 100644 --- a/core/jni/android_util_AssetManager.cpp +++ b/core/jni/android_util_AssetManager.cpp @@ -1536,6 +1536,22 @@ static jint android_content_AssetManager_getGlobalAssetCount(JNIEnv* env, jobjec return Asset::getGlobalCount(); } +static jobject android_content_AssetManager_getAssetAllocations(JNIEnv* env, jobject clazz) +{ + String8 alloc = Asset::getAssetAllocations(); + if (alloc.length() <= 0) { + return NULL; + } + + jstring str = env->NewStringUTF(alloc.string()); + if (str == NULL) { + doThrow(env, "java/lang/OutOfMemoryError"); + return NULL; + } + + return str; +} + static jint android_content_AssetManager_getGlobalAssetManagerCount(JNIEnv* env, jobject clazz) { return AssetManager::getGlobalCount(); @@ -1646,6 +1662,8 @@ static JNINativeMethod gAssetManagerMethods[] = { (void*) android_content_AssetManager_destroy }, { "getGlobalAssetCount", "()I", (void*) android_content_AssetManager_getGlobalAssetCount }, + { "getAssetAllocations", "()Ljava/lang/String;", + (void*) android_content_AssetManager_getAssetAllocations }, { "getGlobalAssetManagerCount", "()I", (void*) android_content_AssetManager_getGlobalAssetCount }, }; diff --git a/include/utils/Asset.h b/include/utils/Asset.h index 453a204..5908bcc 100644 --- a/include/utils/Asset.h +++ b/include/utils/Asset.h @@ -45,6 +45,7 @@ public: virtual ~Asset(void); static int32_t getGlobalCount(); + static String8 getAssetAllocations(); /* used when opening an asset */ typedef enum AccessMode { @@ -110,6 +111,12 @@ public: virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const = 0; /* + * Return whether this asset's buffer is allocated in RAM (not mmapped). + * Note: not virtual so it is safe to call even when being destroyed. + */ + virtual bool isAllocated(void) const { return false; } + + /* * Get a string identifying the asset's source. This might be a full * path, it might be a colon-separated list of identifiers. * @@ -197,6 +204,9 @@ private: AccessMode mAccessMode; // how the asset was opened String8 mAssetSource; // debug string + + Asset* mNext; // linked list. + Asset* mPrev; }; @@ -239,6 +249,7 @@ public: virtual off_t getLength(void) const { return mLength; } virtual off_t getRemainingLength(void) const { return mLength-mOffset; } virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const; + virtual bool isAllocated(void) const { return mBuf != NULL; } private: off_t mStart; // absolute file offset of start of chunk @@ -295,6 +306,7 @@ public: virtual off_t getLength(void) const { return mUncompressedLen; } virtual off_t getRemainingLength(void) const { return mUncompressedLen-mOffset; } virtual int openFileDescriptor(off_t* outStart, off_t* outLength) const { return -1; } + virtual bool isAllocated(void) const { return mBuf != NULL; } private: off_t mStart; // offset to start of compressed data diff --git a/libs/utils/Asset.cpp b/libs/utils/Asset.cpp index 23cb72d..4295123 100644 --- a/libs/utils/Asset.cpp +++ b/libs/utils/Asset.cpp @@ -27,6 +27,7 @@ #include <utils/ZipUtils.h> #include <utils/ZipFileRO.h> #include <utils/Log.h> +#include <utils/threads.h> #include <string.h> #include <memory.h> @@ -40,24 +41,71 @@ using namespace android; # define O_BINARY 0 #endif -static volatile int32_t gCount = 0; +static Mutex gAssetLock; +static int32_t gCount = 0; +static Asset* gHead = NULL; +static Asset* gTail = NULL; int32_t Asset::getGlobalCount() { + AutoMutex _l(gAssetLock); return gCount; } +String8 Asset::getAssetAllocations() +{ + AutoMutex _l(gAssetLock); + String8 res; + Asset* cur = gHead; + while (cur != NULL) { + if (cur->isAllocated()) { + res.append(" "); + res.append(cur->getAssetSource()); + off_t size = (cur->getLength()+512)/1024; + char buf[64]; + sprintf(buf, ": %dK\n", (int)size); + res.append(buf); + } + cur = cur->mNext; + } + + return res; +} + Asset::Asset(void) : mAccessMode(ACCESS_UNKNOWN) { - int count = android_atomic_inc(&gCount)+1; - //LOGI("Creating Asset %p #%d\n", this, count); + AutoMutex _l(gAssetLock); + gCount++; + mNext = mPrev = NULL; + if (gTail == NULL) { + gHead = gTail = this; + } else { + mPrev = gTail; + gTail->mNext = this; + gTail = this; + } + //LOGI("Creating Asset %p #%d\n", this, gCount); } Asset::~Asset(void) { - int count = android_atomic_dec(&gCount); - //LOGI("Destroying Asset in %p #%d\n", this, count); + AutoMutex _l(gAssetLock); + gCount--; + if (gHead == this) { + gHead = mNext; + } + if (gTail == this) { + gTail = mPrev; + } + if (mNext != NULL) { + mNext->mPrev = mPrev; + } + if (mPrev != NULL) { + mPrev->mNext = mNext; + } + mNext = mPrev = NULL; + //LOGI("Destroying Asset in %p #%d\n", this, gCount); } /* diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index ae790c9..04bfae6 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -4449,7 +4449,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } final void appNotRespondingLocked(ProcessRecord app, HistoryRecord activity, - final String annotation) { + HistoryRecord reportedActivity, final String annotation) { if (app.notResponding || app.crashing) { return; } @@ -4477,8 +4477,13 @@ public final class ActivityManagerService extends ActivityManagerNative implemen StringBuilder info = mStringBuilder; info.setLength(0); - info.append("ANR (application not responding) in process: "); + info.append("ANR in process: "); info.append(app.processName); + if (reportedActivity != null && reportedActivity.app != null) { + info.append(" (last in "); + info.append(reportedActivity.app.processName); + info.append(")"); + } if (annotation != null) { info.append("\nAnnotation: "); info.append(annotation); @@ -4498,10 +4503,44 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } else { // Dumping traces to a file so dump all active processes we know about synchronized (this) { - for (int i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) { + // First, these are the most important processes. + final int[] imppids = new int[3]; + int i=0; + imppids[0] = app.pid; + i++; + if (reportedActivity != null && reportedActivity.app != null + && reportedActivity.app.thread != null + && reportedActivity.app.pid != app.pid) { + imppids[i] = reportedActivity.app.pid; + i++; + } + imppids[i] = Process.myPid(); + for (i=0; i<imppids.length && imppids[i] != 0; i++) { + Process.sendSignal(imppids[i], Process.SIGNAL_QUIT); + synchronized (this) { + try { + wait(200); + } catch (InterruptedException e) { + } + } + } + for (i = mLRUProcesses.size() - 1 ; i >= 0 ; i--) { ProcessRecord r = mLRUProcesses.get(i); - if (r.thread != null) { + boolean done = false; + for (int j=0; j<imppids.length && imppids[j] != 0; j++) { + if (imppids[j] == r.pid) { + done = true; + break; + } + } + if (!done && r.thread != null) { Process.sendSignal(r.pid, Process.SIGNAL_QUIT); + synchronized (this) { + try { + wait(200); + } catch (InterruptedException e) { + } + } } } } @@ -4565,7 +4604,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (!dir.exists()) { fileReady = dir.mkdirs(); FileUtils.setPermissions(dir.getAbsolutePath(), - FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IRWXO, -1, -1); + FileUtils.S_IRWXU | FileUtils.S_IRWXG | FileUtils.S_IXOTH, -1, -1); } else if (dir.isDirectory()) { fileReady = true; } @@ -4575,6 +4614,18 @@ public final class ActivityManagerService extends ActivityManagerNative implemen Log.i(TAG, "Removing old ANR trace file from " + tracesPath); fileReady = f.delete(); } + + if (removeExisting) { + try { + f.createNewFile(); + FileUtils.setPermissions(f.getAbsolutePath(), + FileUtils.S_IRWXU | FileUtils.S_IRWXG + | FileUtils.S_IWOTH | FileUtils.S_IROTH, -1, -1); + fileReady = true; + } catch (IOException e) { + Log.w(TAG, "Unable to make ANR traces file", e); + } + } } return fileReady; @@ -10597,7 +10648,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } if (timeout != null && mLRUProcesses.contains(proc)) { Log.w(TAG, "Timeout executing service: " + timeout); - appNotRespondingLocked(proc, null, "Executing service " + appNotRespondingLocked(proc, null, null, "Executing service " + timeout.name); } else { Message msg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG); @@ -11392,7 +11443,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } if (app != null) { - appNotRespondingLocked(app, null, "Broadcast of " + r.intent.toString()); + appNotRespondingLocked(app, null, null, + "Broadcast of " + r.intent.toString()); } if (mPendingBroadcast == r) { diff --git a/services/java/com/android/server/am/HistoryRecord.java b/services/java/com/android/server/am/HistoryRecord.java index b3fc313..84ded22 100644 --- a/services/java/com/android/server/am/HistoryRecord.java +++ b/services/java/com/android/server/am/HistoryRecord.java @@ -470,7 +470,8 @@ class HistoryRecord extends IApplicationToken.Stub { } if (r.app.instrumentationClass == null) { - service.appNotRespondingLocked(r.app, r, "keyDispatchingTimedOut"); + service.appNotRespondingLocked(r.app, r, this, + "keyDispatchingTimedOut"); } else { Bundle info = new Bundle(); info.putString("shortMsg", "keyDispatchingTimedOut"); |