Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f003ae0f authored by Christopher Ferris's avatar Christopher Ferris Committed by Android (Google) Code Review
Browse files

Merge "Implement dumpheap -m."

parents ee21301a 8d652f8f
Loading
Loading
Loading
Loading
+12 −5
Original line number Diff line number Diff line
@@ -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;
@@ -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) {
@@ -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);
@@ -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) {
@@ -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());
        }
+2 −2
Original line number Diff line number Diff line
@@ -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);
+2 −1
Original line number Diff line number Diff line
@@ -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();
+7 −0
Original line number Diff line number Diff line
@@ -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.
     *
+42 −12
Original line number Diff line number Diff line
@@ -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 {
@@ -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() */
@@ -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;
    }

@@ -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);
@@ -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