Loading core/java/android/app/ActivityThread.java +12 −5 Original line number Diff line number Diff line Loading @@ -658,6 +658,8 @@ public final class ActivityThread { } static final class DumpHeapData { public boolean managed; public boolean mallocInfo; public boolean runGc; String path; ParcelFileDescriptor fd; Loading Loading @@ -1025,12 +1027,15 @@ public final class ActivityThread { } @Override public void dumpHeap(boolean managed, boolean runGc, String path, ParcelFileDescriptor fd) { public void dumpHeap(boolean managed, boolean mallocInfo, boolean runGc, String path, ParcelFileDescriptor fd) { DumpHeapData dhd = new DumpHeapData(); dhd.managed = managed; dhd.mallocInfo = mallocInfo; dhd.runGc = runGc; dhd.path = path; dhd.fd = fd; sendMessage(H.DUMP_HEAP, dhd, managed ? 1 : 0, 0, true /*async*/); sendMessage(H.DUMP_HEAP, dhd, 0, 0, true /*async*/); } public void attachAgent(String agent) { Loading Loading @@ -1762,7 +1767,7 @@ public final class ActivityThread { case SCHEDULE_CRASH: throw new RemoteServiceException((String)msg.obj); case DUMP_HEAP: handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj); handleDumpHeap((DumpHeapData) msg.obj); break; case DUMP_ACTIVITY: handleDumpActivity((DumpComponentInfo)msg.obj); Loading Loading @@ -5173,13 +5178,13 @@ public final class ActivityThread { } } static final void handleDumpHeap(boolean managed, DumpHeapData dhd) { static void handleDumpHeap(DumpHeapData dhd) { if (dhd.runGc) { System.gc(); System.runFinalization(); System.gc(); } if (managed) { if (dhd.managed) { try { Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor()); } catch (IOException e) { Loading @@ -5192,6 +5197,8 @@ public final class ActivityThread { Slog.w(TAG, "Failure closing profile fd", e); } } } else if (dhd.mallocInfo) { Debug.dumpNativeMallocInfo(dhd.fd.getFileDescriptor()); } else { Debug.dumpNativeHeap(dhd.fd.getFileDescriptor()); } Loading core/java/android/app/IActivityManager.aidl +2 −2 Original line number Diff line number Diff line Loading @@ -277,8 +277,8 @@ interface IActivityManager { int checkGrantUriPermission(int callingUid, in String targetPkg, in Uri uri, int modeFlags, int userId); // Cause the specified process to dump the specified heap. boolean dumpHeap(in String process, int userId, boolean managed, boolean runGc, in String path, in ParcelFileDescriptor fd); boolean dumpHeap(in String process, int userId, boolean managed, boolean mallocInfo, boolean runGc, in String path, in ParcelFileDescriptor fd); int startActivities(in IApplicationThread caller, in String callingPackage, in Intent[] intents, in String[] resolvedTypes, in IBinder resultTo, in Bundle options, int userId); Loading core/java/android/app/IApplicationThread.aidl +2 −1 Original line number Diff line number Diff line Loading @@ -117,7 +117,8 @@ oneway interface IApplicationThread { void scheduleSuicide(); void dispatchPackageBroadcast(int cmd, in String[] packages); void scheduleCrash(in String msg); void dumpHeap(boolean managed, boolean runGc, in String path, in ParcelFileDescriptor fd); void dumpHeap(boolean managed, boolean mallocInfo, boolean runGc, in String path, in ParcelFileDescriptor fd); void dumpActivity(in ParcelFileDescriptor fd, IBinder servicetoken, in String prefix, in String[] args); void clearDnsCache(); Loading core/java/android/os/Debug.java +7 −0 Original line number Diff line number Diff line Loading @@ -1813,6 +1813,13 @@ public final class Debug */ public static native void dumpNativeHeap(FileDescriptor fd); /** * Writes malloc info data to the specified file descriptor. * * @hide */ public static native void dumpNativeMallocInfo(FileDescriptor fd); /** * Returns a count of the extant instances of a class. * Loading core/jni/android_os_Debug.cpp +42 −12 Original line number Diff line number Diff line Loading @@ -48,10 +48,14 @@ namespace android { using UniqueFile = std::unique_ptr<FILE, decltype(&fclose)>; static void safeFclose(FILE* fp) { if (fp) fclose(fp); } using UniqueFile = std::unique_ptr<FILE, decltype(&safeFclose)>; static inline UniqueFile MakeUniqueFile(const char* path, const char* mode) { return UniqueFile(fopen(path, mode), fclose); return UniqueFile(fopen(path, mode), safeFclose); } enum { Loading Loading @@ -972,21 +976,16 @@ static void dumpNativeHeap(FILE* fp) fprintf(fp, "END\n"); } /* * Dump the native heap, writing human-readable output to the specified * file descriptor. */ static void android_os_Debug_dumpNativeHeap(JNIEnv* env, jobject clazz, jobject fileDescriptor) static bool openFile(JNIEnv* env, jobject fileDescriptor, UniqueFile& fp) { if (fileDescriptor == NULL) { jniThrowNullPointerException(env, "fd == null"); return; return false; } int origFd = jniGetFDFromFileDescriptor(env, fileDescriptor); if (origFd < 0) { jniThrowRuntimeException(env, "Invalid file descriptor"); return; return false; } /* dup() the descriptor so we don't close the original with fclose() */ Loading @@ -994,14 +993,28 @@ static void android_os_Debug_dumpNativeHeap(JNIEnv* env, jobject clazz, if (fd < 0) { ALOGW("dup(%d) failed: %s\n", origFd, strerror(errno)); jniThrowRuntimeException(env, "dup() failed"); return; return false; } UniqueFile fp(fdopen(fd, "w"), fclose); fp.reset(fdopen(fd, "w")); if (fp == nullptr) { ALOGW("fdopen(%d) failed: %s\n", fd, strerror(errno)); close(fd); jniThrowRuntimeException(env, "fdopen() failed"); return false; } return true; } /* * Dump the native heap, writing human-readable output to the specified * file descriptor. */ static void android_os_Debug_dumpNativeHeap(JNIEnv* env, jobject, jobject fileDescriptor) { UniqueFile fp(nullptr, safeFclose); if (!openFile(env, fileDescriptor, fp)) { return; } Loading @@ -1010,6 +1023,21 @@ static void android_os_Debug_dumpNativeHeap(JNIEnv* env, jobject clazz, ALOGD("Native heap dump complete.\n"); } /* * Dump the native malloc info, writing xml output to the specified * file descriptor. */ static void android_os_Debug_dumpNativeMallocInfo(JNIEnv* env, jobject, jobject fileDescriptor) { UniqueFile fp(nullptr, safeFclose); if (!openFile(env, fileDescriptor, fp)) { return; } malloc_info(0, fp.get()); } static bool dumpTraces(JNIEnv* env, jint pid, jstring fileName, jint timeoutSecs, DebuggerdDumpType dumpType) { const ScopedUtfChars fileNameChars(env, fileName); Loading Loading @@ -1070,6 +1098,8 @@ static const JNINativeMethod gMethods[] = { (void*) android_os_Debug_getMemInfo }, { "dumpNativeHeap", "(Ljava/io/FileDescriptor;)V", (void*) android_os_Debug_dumpNativeHeap }, { "dumpNativeMallocInfo", "(Ljava/io/FileDescriptor;)V", (void*) android_os_Debug_dumpNativeMallocInfo }, { "getBinderSentTransactions", "()I", (void*) android_os_Debug_getBinderSentTransactions }, { "getBinderReceivedTransactions", "()I", Loading Loading
core/java/android/app/ActivityThread.java +12 −5 Original line number Diff line number Diff line Loading @@ -658,6 +658,8 @@ public final class ActivityThread { } static final class DumpHeapData { public boolean managed; public boolean mallocInfo; public boolean runGc; String path; ParcelFileDescriptor fd; Loading Loading @@ -1025,12 +1027,15 @@ public final class ActivityThread { } @Override public void dumpHeap(boolean managed, boolean runGc, String path, ParcelFileDescriptor fd) { public void dumpHeap(boolean managed, boolean mallocInfo, boolean runGc, String path, ParcelFileDescriptor fd) { DumpHeapData dhd = new DumpHeapData(); dhd.managed = managed; dhd.mallocInfo = mallocInfo; dhd.runGc = runGc; dhd.path = path; dhd.fd = fd; sendMessage(H.DUMP_HEAP, dhd, managed ? 1 : 0, 0, true /*async*/); sendMessage(H.DUMP_HEAP, dhd, 0, 0, true /*async*/); } public void attachAgent(String agent) { Loading Loading @@ -1762,7 +1767,7 @@ public final class ActivityThread { case SCHEDULE_CRASH: throw new RemoteServiceException((String)msg.obj); case DUMP_HEAP: handleDumpHeap(msg.arg1 != 0, (DumpHeapData)msg.obj); handleDumpHeap((DumpHeapData) msg.obj); break; case DUMP_ACTIVITY: handleDumpActivity((DumpComponentInfo)msg.obj); Loading Loading @@ -5173,13 +5178,13 @@ public final class ActivityThread { } } static final void handleDumpHeap(boolean managed, DumpHeapData dhd) { static void handleDumpHeap(DumpHeapData dhd) { if (dhd.runGc) { System.gc(); System.runFinalization(); System.gc(); } if (managed) { if (dhd.managed) { try { Debug.dumpHprofData(dhd.path, dhd.fd.getFileDescriptor()); } catch (IOException e) { Loading @@ -5192,6 +5197,8 @@ public final class ActivityThread { Slog.w(TAG, "Failure closing profile fd", e); } } } else if (dhd.mallocInfo) { Debug.dumpNativeMallocInfo(dhd.fd.getFileDescriptor()); } else { Debug.dumpNativeHeap(dhd.fd.getFileDescriptor()); } Loading
core/java/android/app/IActivityManager.aidl +2 −2 Original line number Diff line number Diff line Loading @@ -277,8 +277,8 @@ interface IActivityManager { int checkGrantUriPermission(int callingUid, in String targetPkg, in Uri uri, int modeFlags, int userId); // Cause the specified process to dump the specified heap. boolean dumpHeap(in String process, int userId, boolean managed, boolean runGc, in String path, in ParcelFileDescriptor fd); boolean dumpHeap(in String process, int userId, boolean managed, boolean mallocInfo, boolean runGc, in String path, in ParcelFileDescriptor fd); int startActivities(in IApplicationThread caller, in String callingPackage, in Intent[] intents, in String[] resolvedTypes, in IBinder resultTo, in Bundle options, int userId); Loading
core/java/android/app/IApplicationThread.aidl +2 −1 Original line number Diff line number Diff line Loading @@ -117,7 +117,8 @@ oneway interface IApplicationThread { void scheduleSuicide(); void dispatchPackageBroadcast(int cmd, in String[] packages); void scheduleCrash(in String msg); void dumpHeap(boolean managed, boolean runGc, in String path, in ParcelFileDescriptor fd); void dumpHeap(boolean managed, boolean mallocInfo, boolean runGc, in String path, in ParcelFileDescriptor fd); void dumpActivity(in ParcelFileDescriptor fd, IBinder servicetoken, in String prefix, in String[] args); void clearDnsCache(); Loading
core/java/android/os/Debug.java +7 −0 Original line number Diff line number Diff line Loading @@ -1813,6 +1813,13 @@ public final class Debug */ public static native void dumpNativeHeap(FileDescriptor fd); /** * Writes malloc info data to the specified file descriptor. * * @hide */ public static native void dumpNativeMallocInfo(FileDescriptor fd); /** * Returns a count of the extant instances of a class. * Loading
core/jni/android_os_Debug.cpp +42 −12 Original line number Diff line number Diff line Loading @@ -48,10 +48,14 @@ namespace android { using UniqueFile = std::unique_ptr<FILE, decltype(&fclose)>; static void safeFclose(FILE* fp) { if (fp) fclose(fp); } using UniqueFile = std::unique_ptr<FILE, decltype(&safeFclose)>; static inline UniqueFile MakeUniqueFile(const char* path, const char* mode) { return UniqueFile(fopen(path, mode), fclose); return UniqueFile(fopen(path, mode), safeFclose); } enum { Loading Loading @@ -972,21 +976,16 @@ static void dumpNativeHeap(FILE* fp) fprintf(fp, "END\n"); } /* * Dump the native heap, writing human-readable output to the specified * file descriptor. */ static void android_os_Debug_dumpNativeHeap(JNIEnv* env, jobject clazz, jobject fileDescriptor) static bool openFile(JNIEnv* env, jobject fileDescriptor, UniqueFile& fp) { if (fileDescriptor == NULL) { jniThrowNullPointerException(env, "fd == null"); return; return false; } int origFd = jniGetFDFromFileDescriptor(env, fileDescriptor); if (origFd < 0) { jniThrowRuntimeException(env, "Invalid file descriptor"); return; return false; } /* dup() the descriptor so we don't close the original with fclose() */ Loading @@ -994,14 +993,28 @@ static void android_os_Debug_dumpNativeHeap(JNIEnv* env, jobject clazz, if (fd < 0) { ALOGW("dup(%d) failed: %s\n", origFd, strerror(errno)); jniThrowRuntimeException(env, "dup() failed"); return; return false; } UniqueFile fp(fdopen(fd, "w"), fclose); fp.reset(fdopen(fd, "w")); if (fp == nullptr) { ALOGW("fdopen(%d) failed: %s\n", fd, strerror(errno)); close(fd); jniThrowRuntimeException(env, "fdopen() failed"); return false; } return true; } /* * Dump the native heap, writing human-readable output to the specified * file descriptor. */ static void android_os_Debug_dumpNativeHeap(JNIEnv* env, jobject, jobject fileDescriptor) { UniqueFile fp(nullptr, safeFclose); if (!openFile(env, fileDescriptor, fp)) { return; } Loading @@ -1010,6 +1023,21 @@ static void android_os_Debug_dumpNativeHeap(JNIEnv* env, jobject clazz, ALOGD("Native heap dump complete.\n"); } /* * Dump the native malloc info, writing xml output to the specified * file descriptor. */ static void android_os_Debug_dumpNativeMallocInfo(JNIEnv* env, jobject, jobject fileDescriptor) { UniqueFile fp(nullptr, safeFclose); if (!openFile(env, fileDescriptor, fp)) { return; } malloc_info(0, fp.get()); } static bool dumpTraces(JNIEnv* env, jint pid, jstring fileName, jint timeoutSecs, DebuggerdDumpType dumpType) { const ScopedUtfChars fileNameChars(env, fileName); Loading Loading @@ -1070,6 +1098,8 @@ static const JNINativeMethod gMethods[] = { (void*) android_os_Debug_getMemInfo }, { "dumpNativeHeap", "(Ljava/io/FileDescriptor;)V", (void*) android_os_Debug_dumpNativeHeap }, { "dumpNativeMallocInfo", "(Ljava/io/FileDescriptor;)V", (void*) android_os_Debug_dumpNativeMallocInfo }, { "getBinderSentTransactions", "()I", (void*) android_os_Debug_getBinderSentTransactions }, { "getBinderReceivedTransactions", "()I", Loading