am b8546001: Merge change 20878 into donut
Merge commit 'b8546001701405a76dad7e6235046e592296fac2' * commit 'b8546001701405a76dad7e6235046e592296fac2': Fix issue #2048263: More debugging information
This commit is contained in:
@@ -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) {
|
||||
|
||||
@@ -664,6 +664,11 @@ public final class AssetManager {
|
||||
*/
|
||||
public native static final int getGlobalAssetCount();
|
||||
|
||||
/**
|
||||
* {@hide}
|
||||
*/
|
||||
public native static final String getAssetAllocations();
|
||||
|
||||
/**
|
||||
* {@hide}
|
||||
*/
|
||||
|
||||
@@ -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 },
|
||||
};
|
||||
|
||||
@@ -45,6 +45,7 @@ public:
|
||||
virtual ~Asset(void);
|
||||
|
||||
static int32_t getGlobalCount();
|
||||
static String8 getAssetAllocations();
|
||||
|
||||
/* used when opening an asset */
|
||||
typedef enum AccessMode {
|
||||
@@ -109,6 +110,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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -4455,7 +4455,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;
|
||||
}
|
||||
@@ -4483,8 +4483,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);
|
||||
@@ -4504,10 +4509,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) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4571,7 +4610,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;
|
||||
}
|
||||
@@ -4581,6 +4620,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;
|
||||
@@ -10639,7 +10690,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);
|
||||
@@ -11434,7 +11485,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) {
|
||||
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user