19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2007 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden#define LOG_TAG "android.os.Debug" 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "JNIHelp.h" 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "jni.h" 20f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn#include <utils/String8.h> 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include "utils/misc.h" 22f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn#include "cutils/debugger.h" 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn#include <fcntl.h> 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h> 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h> 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h> 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h> 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <time.h> 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/time.h> 3106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden#include <errno.h> 3206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden#include <assert.h> 330e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn#include <ctype.h> 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_MALLOC_H 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <malloc.h> 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 420e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackbornenum { 430e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_UNKNOWN, 440e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_DALVIK, 450e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_NATIVE, 467c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers HEAP_STACK, 470e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_CURSOR, 480e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_ASHMEM, 490e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_UNKNOWN_DEV, 500e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_SO, 510e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_JAR, 520e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_APK, 530e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_TTF, 540e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_DEX, 550e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_UNKNOWN_MAP, 560e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 570e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn _NUM_HEAP, 580e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn _NUM_CORE_HEAP = HEAP_NATIVE+1 590e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn}; 600e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 610e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackbornstruct stat_fields { 620e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn jfieldID pss_field; 630e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn jfieldID privateDirty_field; 640e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn jfieldID sharedDirty_field; 650e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn}; 660e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 670e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackbornstruct stat_field_names { 680e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn const char* pss_name; 690e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn const char* privateDirty_name; 700e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn const char* sharedDirty_name; 710e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn}; 720e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 730e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackbornstatic stat_fields stat_fields[_NUM_CORE_HEAP]; 740e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 750e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackbornstatic stat_field_names stat_field_names[_NUM_CORE_HEAP] = { 760e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn { "otherPss", "otherPrivateDirty", "otherSharedDirty" }, 770e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn { "dalvikPss", "dalvikPrivateDirty", "dalvikSharedDirty" }, 780e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn { "nativePss", "nativePrivateDirty", "nativeSharedDirty" } 790e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn}; 800e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 810e3328fbdd3845b0e2bec364e951498eaee6b079Dianne HackbornjfieldID otherStats_field; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct stats_t { 840e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int pss; 850e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int privateDirty; 860e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int sharedDirty; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define BINDER_STATS "/proc/binder/stats" 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jlong android_os_Debug_getNativeHeapSize(JNIEnv *env, jobject clazz) 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_MALLOC_H 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct mallinfo info = mallinfo(); 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jlong) info.usmblks; 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jlong android_os_Debug_getNativeHeapAllocatedSize(JNIEnv *env, jobject clazz) 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_MALLOC_H 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct mallinfo info = mallinfo(); 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jlong) info.uordblks; 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jlong android_os_Debug_getNativeHeapFreeSize(JNIEnv *env, jobject clazz) 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1137c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers#ifdef HAVE_MALLOC_H 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct mallinfo info = mallinfo(); 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jlong) info.fordblks; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void read_mapinfo(FILE *fp, stats_t* stats) 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char line[1024]; 1240e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int len, nameLen; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool skip, done = false; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1270e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn unsigned size = 0, resident = 0, pss = 0; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned shared_clean = 0, shared_dirty = 0; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned private_clean = 0, private_dirty = 0; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned referenced = 0; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned temp; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1330e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn unsigned long int start; 1340e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn unsigned long int end = 0; 1350e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn unsigned long int prevEnd = 0; 1360e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn char* name; 1370e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int name_pos; 1380e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 1390e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int whichHeap = HEAP_UNKNOWN; 1400e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int prevHeap = HEAP_UNKNOWN; 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1420e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn if(fgets(line, sizeof(line), fp) == 0) return; 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (!done) { 1450e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn prevHeap = whichHeap; 1460e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn prevEnd = end; 1470e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_UNKNOWN; 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project skip = false; 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len = strlen(line); 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len < 1) return; 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project line[--len] = 0; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1540e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn if (sscanf(line, "%lx-%lx %*s %*x %*x:%*x %*d%n", &start, &end, &name_pos) != 2) { 1550e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn skip = true; 1560e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else { 1570e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn while (isspace(line[name_pos])) { 1580e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn name_pos += 1; 1590e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 1600e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn name = line + name_pos; 1610e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn nameLen = strlen(name); 1620e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 163afc10e174d73363185f42cb67ec429a64549f2c7Ian Rogers if ((strstr(name, "[heap]") == name) || 164afc10e174d73363185f42cb67ec429a64549f2c7Ian Rogers (strstr(name, "/dev/ashmem/libc malloc") == name)) { 1650e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_NATIVE; 1660e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (strstr(name, "/dev/ashmem/dalvik-") == name) { 1670e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_DALVIK; 1687c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers } else if (strstr(name, "[stack") == name) { 1697c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers whichHeap = HEAP_STACK; 1700e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (strstr(name, "/dev/ashmem/CursorWindow") == name) { 1710e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_CURSOR; 1720e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (strstr(name, "/dev/ashmem/") == name) { 1730e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_ASHMEM; 1740e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (strstr(name, "/dev/") == name) { 1750e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_UNKNOWN_DEV; 1760e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (nameLen > 3 && strcmp(name+nameLen-3, ".so") == 0) { 1770e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_SO; 1780e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (nameLen > 4 && strcmp(name+nameLen-4, ".jar") == 0) { 1790e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_JAR; 1800e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (nameLen > 4 && strcmp(name+nameLen-4, ".apk") == 0) { 1810e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_APK; 1820e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (nameLen > 4 && strcmp(name+nameLen-4, ".ttf") == 0) { 1830e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_TTF; 1849f8589c31f8910a9c3c33a81675822da9f0cf2dfIan Rogers } else if ((nameLen > 4 && strcmp(name+nameLen-4, ".dex") == 0) || 1859f8589c31f8910a9c3c33a81675822da9f0cf2dfIan Rogers (nameLen > 5 && strcmp(name+nameLen-5, ".odex") == 0)) { 1860e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_DEX; 1870e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (nameLen > 0) { 1880e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_UNKNOWN_MAP; 1890e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (start == prevEnd && prevHeap == HEAP_SO) { 1900e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn // bss section of a shared library. 1910e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_SO; 1920e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1956215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("native=%d dalvik=%d sqlite=%d: %s\n", isNativeHeap, isDalvikHeap, 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // isSqliteHeap, line); 1977c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (true) { 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fgets(line, 1024, fp) == 0) { 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project done = true; 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sscanf(line, "Size: %d kB", &temp) == 1) { 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size = temp; 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (sscanf(line, "Rss: %d kB", &temp) == 1) { 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resident = temp; 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (sscanf(line, "Pss: %d kB", &temp) == 1) { 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pss = temp; 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (sscanf(line, "Shared_Clean: %d kB", &temp) == 1) { 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shared_clean = temp; 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (sscanf(line, "Shared_Dirty: %d kB", &temp) == 1) { 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shared_dirty = temp; 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (sscanf(line, "Private_Clean: %d kB", &temp) == 1) { 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private_clean = temp; 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (sscanf(line, "Private_Dirty: %d kB", &temp) == 1) { 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private_dirty = temp; 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (sscanf(line, "Referenced: %d kB", &temp) == 1) { 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project referenced = temp; 220bd51116a5310683f70a37110bf735252dc7e4e38Grace Kloba } else if (strlen(line) > 30 && line[8] == '-' && line[17] == ' ') { 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // looks like a new mapping 222bd51116a5310683f70a37110bf735252dc7e4e38Grace Kloba // example: "10000000-10001000 ---p 10000000 00:00 0" 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!skip) { 2280e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats[whichHeap].pss += pss; 2290e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats[whichHeap].privateDirty += private_dirty; 2300e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats[whichHeap].sharedDirty += shared_dirty; 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void load_maps(int pid, stats_t* stats) 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char tmp[128]; 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FILE *fp; 2397c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sprintf(tmp, "/proc/%d/smaps", pid); 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fp = fopen(tmp, "r"); 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fp == 0) return; 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project read_mapinfo(fp, stats); 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fclose(fp); 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2483025ef332c29e255388f74b2afefe05f64bce07cDianne Hackbornstatic void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, 2493025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn jint pid, jobject object) 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2510e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats_t stats[_NUM_HEAP]; 2520e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn memset(&stats, 0, sizeof(stats)); 2537c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 2540e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn load_maps(pid, stats); 2550e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 2560e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn for (int i=_NUM_CORE_HEAP; i<_NUM_HEAP; i++) { 2570e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats[HEAP_UNKNOWN].pss += stats[i].pss; 2580e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats[HEAP_UNKNOWN].privateDirty += stats[i].privateDirty; 2590e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats[HEAP_UNKNOWN].sharedDirty += stats[i].sharedDirty; 2600e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2620e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn for (int i=0; i<_NUM_CORE_HEAP; i++) { 2630e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->SetIntField(object, stat_fields[i].pss_field, stats[i].pss); 2640e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->SetIntField(object, stat_fields[i].privateDirty_field, stats[i].privateDirty); 2650e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->SetIntField(object, stat_fields[i].sharedDirty_field, stats[i].sharedDirty); 2660e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 2677c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 2680e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn jintArray otherIntArray = (jintArray)env->GetObjectField(object, otherStats_field); 2697c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 2700e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn jint* otherArray = (jint*)env->GetPrimitiveArrayCritical(otherIntArray, 0); 2710e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn if (otherArray == NULL) { 2720e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn return; 2730e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 2740e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 2750e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int j=0; 2760e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn for (int i=_NUM_CORE_HEAP; i<_NUM_HEAP; i++) { 2770e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn otherArray[j++] = stats[i].pss; 2780e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn otherArray[j++] = stats[i].privateDirty; 2790e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn otherArray[j++] = stats[i].sharedDirty; 2800e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 2810e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 2820e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->ReleasePrimitiveArrayCritical(otherIntArray, otherArray, 0); 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2853025ef332c29e255388f74b2afefe05f64bce07cDianne Hackbornstatic void android_os_Debug_getDirtyPages(JNIEnv *env, jobject clazz, jobject object) 2863025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn{ 2873025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn android_os_Debug_getDirtyPagesPid(env, clazz, getpid(), object); 2883025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn} 2893025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn 290b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackbornstatic jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid) 291b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn{ 292b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn char line[1024]; 293b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn jlong pss = 0; 294b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn unsigned temp; 295b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 296b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn char tmp[128]; 297b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn FILE *fp; 298b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 299b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn sprintf(tmp, "/proc/%d/smaps", pid); 300b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn fp = fopen(tmp, "r"); 301b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn if (fp == 0) return 0; 302b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 303b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn while (true) { 304b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn if (fgets(line, 1024, fp) == 0) { 305b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn break; 306b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn } 307b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 308b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn if (sscanf(line, "Pss: %d kB", &temp) == 1) { 309b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn pss += temp; 310b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn } 311b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn } 312b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 313b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn fclose(fp); 314b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 315b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn return pss; 316b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn} 317b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 318b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackbornstatic jlong android_os_Debug_getPss(JNIEnv *env, jobject clazz) 319b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn{ 320b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn return android_os_Debug_getPssPid(env, clazz, getpid()); 321b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn} 322b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint read_binder_stat(const char* stat) 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FILE* fp = fopen(BINDER_STATS, "r"); 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fp == NULL) { 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char line[1024]; 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char compare[128]; 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int len = snprintf(compare, 128, "proc %d", getpid()); 3347c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // loop until we have the block that represents this process 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fgets(line, 1024, fp) == 0) { 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (strncmp(compare, line, len)); 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3427c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers // now that we have this process, read until we find the stat that we are looking for 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len = snprintf(compare, 128, " %s: ", stat); 3447c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fgets(line, 1024, fp) == 0) { 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (strncmp(compare, line, len)); 3507c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we have the line, now increment the line ptr to the value 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char* ptr = line + len; 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return atoi(ptr); 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_os_Debug_getBinderSentTransactions(JNIEnv *env, jobject clazz) 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return read_binder_stat("bcTRANSACTION"); 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_os_getBinderReceivedTransactions(JNIEnv *env, jobject clazz) 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return read_binder_stat("brTRANSACTION"); 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// these are implemented in android_util_Binder.cpp 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz); 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz); 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz); 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 37106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 37206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden/* pulled out of bionic */ 37306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFaddenextern "C" void get_malloc_leak_info(uint8_t** info, size_t* overallSize, 37406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t* infoSize, size_t* totalMemory, size_t* backtraceSize); 37506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFaddenextern "C" void free_malloc_leak_info(uint8_t* info); 37606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden#define SIZE_FLAG_ZYGOTE_CHILD (1<<31) 37706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden#define BACKTRACE_SIZE 32 37806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 37906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden/* 38006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * This is a qsort() callback. 38106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * 38206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * See dumpNativeHeap() for comments about the data format and sort order. 38306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden */ 38406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFaddenstatic int compareHeapRecords(const void* vrec1, const void* vrec2) 38506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden{ 38606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden const size_t* rec1 = (const size_t*) vrec1; 38706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden const size_t* rec2 = (const size_t*) vrec2; 38806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t size1 = *rec1; 38906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t size2 = *rec2; 39006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 39106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (size1 < size2) { 39206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return 1; 39306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } else if (size1 > size2) { 39406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return -1; 39506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 39606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 39706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden intptr_t* bt1 = (intptr_t*)(rec1 + 2); 39806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden intptr_t* bt2 = (intptr_t*)(rec2 + 2); 39906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden for (size_t idx = 0; idx < BACKTRACE_SIZE; idx++) { 40006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden intptr_t addr1 = bt1[idx]; 40106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden intptr_t addr2 = bt2[idx]; 40206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (addr1 == addr2) { 40306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (addr1 == 0) 40406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden break; 40506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden continue; 40606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 40706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (addr1 < addr2) { 40806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return -1; 40906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } else if (addr1 > addr2) { 41006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return 1; 41106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 41206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 41306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 41406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return 0; 41506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden} 41606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 41706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden/* 41806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * The get_malloc_leak_info() call returns an array of structs that 41906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * look like this: 42006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * 42106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * size_t size 42206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * size_t allocations 42306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * intptr_t backtrace[32] 42406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * 42506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * "size" is the size of the allocation, "backtrace" is a fixed-size 42606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * array of function pointers, and "allocations" is the number of 42706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * allocations with the exact same size and backtrace. 42806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * 42906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * The entries are sorted by descending total size (i.e. size*allocations) 43006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * then allocation count. For best results with "diff" we'd like to sort 43106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * primarily by individual size then stack trace. Since the entries are 43206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * fixed-size, and we're allowed (by the current implementation) to mangle 43306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * them, we can do this in place. 43406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden */ 43506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFaddenstatic void dumpNativeHeap(FILE* fp) 43606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden{ 43706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden uint8_t* info = NULL; 43806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t overallSize, infoSize, totalMemory, backtraceSize; 43906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 44006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden get_malloc_leak_info(&info, &overallSize, &infoSize, &totalMemory, 44106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden &backtraceSize); 44206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (info == NULL) { 44306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "Native heap dump not available. To enable, run these" 44406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden " commands (requires root):\n"); 44506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "$ adb shell setprop libc.debug.malloc 1\n"); 44606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "$ adb shell stop\n"); 44706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "$ adb shell start\n"); 44806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return; 44906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 45006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden assert(infoSize != 0); 45106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden assert(overallSize % infoSize == 0); 45206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 45306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "Android Native Heap Dump v1.0\n\n"); 45406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 45506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t recordCount = overallSize / infoSize; 45606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "Total memory: %zu\n", totalMemory); 45706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "Allocation records: %zd\n", recordCount); 45806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (backtraceSize != BACKTRACE_SIZE) { 45906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "WARNING: mismatched backtrace sizes (%d vs. %d)\n", 46006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden backtraceSize, BACKTRACE_SIZE); 46106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 46206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "\n"); 46306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 46406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden /* re-sort the entries */ 46506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden qsort(info, recordCount, infoSize, compareHeapRecords); 46606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 46706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden /* dump the entries to the file */ 46806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden const uint8_t* ptr = info; 46906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden for (size_t idx = 0; idx < recordCount; idx++) { 47006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t size = *(size_t*) ptr; 47106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t allocations = *(size_t*) (ptr + sizeof(size_t)); 47206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden intptr_t* backtrace = (intptr_t*) (ptr + sizeof(size_t) * 2); 47306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 47406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "z %d sz %8zu num %4zu bt", 47506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden (size & SIZE_FLAG_ZYGOTE_CHILD) != 0, 47606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size & ~SIZE_FLAG_ZYGOTE_CHILD, 47706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden allocations); 47806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden for (size_t bt = 0; bt < backtraceSize; bt++) { 47906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (backtrace[bt] == 0) { 48006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden break; 48106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } else { 48206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, " %08x", backtrace[bt]); 48306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 48406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 48506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "\n"); 48606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 48706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden ptr += infoSize; 48806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 48906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 49006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden free_malloc_leak_info(info); 491393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom 492393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom fprintf(fp, "MAPS\n"); 493393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom const char* maps = "/proc/self/maps"; 494393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom FILE* in = fopen(maps, "r"); 495393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom if (in == NULL) { 496393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom fprintf(fp, "Could not open %s\n", maps); 497393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom return; 498393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom } 499393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom char buf[BUFSIZ]; 500393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom while (size_t n = fread(buf, sizeof(char), BUFSIZ, in)) { 501393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom fwrite(buf, sizeof(char), n, fp); 502393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom } 503393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom fclose(in); 504393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom 505393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom fprintf(fp, "END\n"); 50606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden} 50706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 50806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden/* 50906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * Dump the native heap, writing human-readable output to the specified 51006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * file descriptor. 51106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden */ 51206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFaddenstatic void android_os_Debug_dumpNativeHeap(JNIEnv* env, jobject clazz, 51306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden jobject fileDescriptor) 51406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden{ 51506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (fileDescriptor == NULL) { 5167c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers jniThrowNullPointerException(env, "fd == null"); 51706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return; 51806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 51906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden int origFd = jniGetFDFromFileDescriptor(env, fileDescriptor); 52006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (origFd < 0) { 52106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden jniThrowRuntimeException(env, "Invalid file descriptor"); 52206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return; 52306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 52406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 52506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden /* dup() the descriptor so we don't close the original with fclose() */ 52606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden int fd = dup(origFd); 52706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (fd < 0) { 5288564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("dup(%d) failed: %s\n", origFd, strerror(errno)); 52906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden jniThrowRuntimeException(env, "dup() failed"); 53006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return; 53106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 53206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 53306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden FILE* fp = fdopen(fd, "w"); 53406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (fp == NULL) { 5358564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("fdopen(%d) failed: %s\n", fd, strerror(errno)); 53606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden close(fd); 53706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden jniThrowRuntimeException(env, "fdopen() failed"); 53806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return; 53906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 54006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 5415baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("Native heap dump starting...\n"); 54206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden dumpNativeHeap(fp); 5435baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("Native heap dump complete.\n"); 54406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 54506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fclose(fp); 54606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden} 54706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 54806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 549f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackbornstatic void android_os_Debug_dumpNativeBacktraceToFile(JNIEnv* env, jobject clazz, 550f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn jint pid, jstring fileName) 551f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn{ 552f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn if (fileName == NULL) { 5537c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers jniThrowNullPointerException(env, "file == null"); 554f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn return; 555f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn } 556f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn const jchar* str = env->GetStringCritical(fileName, 0); 557f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn String8 fileName8; 558f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn if (str) { 559f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn fileName8 = String8(str, env->GetStringLength(fileName)); 560f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn env->ReleaseStringCritical(fileName, str); 561f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn } 562f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn 563f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn int fd = open(fileName8.string(), O_CREAT | O_WRONLY | O_NOFOLLOW, 0666); /* -rw-rw-rw- */ 564f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn if (fd < 0) { 565f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn fprintf(stderr, "Can't open %s: %s\n", fileName8.string(), strerror(errno)); 566f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn return; 567f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn } 568f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn 569f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn if (lseek(fd, 0, SEEK_END) < 0) { 570f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn fprintf(stderr, "lseek: %s\n", strerror(errno)); 571f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn } else { 572f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn dump_backtrace_to_file(pid, fd); 573f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn } 574f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn 575f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn close(fd); 576f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn} 577f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * JNI registration. 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gMethods[] = { 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getNativeHeapSize", "()J", 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_os_Debug_getNativeHeapSize }, 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getNativeHeapAllocatedSize", "()J", 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_os_Debug_getNativeHeapAllocatedSize }, 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getNativeHeapFreeSize", "()J", 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_os_Debug_getNativeHeapFreeSize }, 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getMemoryInfo", "(Landroid/os/Debug$MemoryInfo;)V", 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_os_Debug_getDirtyPages }, 5913025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn { "getMemoryInfo", "(ILandroid/os/Debug$MemoryInfo;)V", 5923025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn (void*) android_os_Debug_getDirtyPagesPid }, 593b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn { "getPss", "()J", 594b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn (void*) android_os_Debug_getPss }, 595b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn { "getPss", "(I)J", 596b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn (void*) android_os_Debug_getPssPid }, 59706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden { "dumpNativeHeap", "(Ljava/io/FileDescriptor;)V", 59806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden (void*) android_os_Debug_dumpNativeHeap }, 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getBinderSentTransactions", "()I", 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_os_Debug_getBinderSentTransactions }, 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getBinderReceivedTransactions", "()I", 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_os_getBinderReceivedTransactions }, 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getBinderLocalObjectCount", "()I", 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)android_os_Debug_getLocalObjectCount }, 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getBinderProxyObjectCount", "()I", 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)android_os_Debug_getProxyObjectCount }, 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getBinderDeathObjectCount", "()I", 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)android_os_Debug_getDeathObjectCount }, 609f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn { "dumpNativeBacktraceToFile", "(ILjava/lang/String;)V", 610f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn (void*)android_os_Debug_dumpNativeBacktraceToFile }, 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_os_Debug(JNIEnv *env) 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jclass clazz = env->FindClass("android/os/Debug$MemoryInfo"); 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6177c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers // Sanity check the number of other statistics expected in Java matches here. 6187c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers jfieldID numOtherStats_field = env->GetStaticFieldID(clazz, "NUM_OTHER_STATS", "I"); 6197c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers jint numOtherStats = env->GetStaticIntField(clazz, numOtherStats_field); 6207c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers int expectedNumOtherStats = _NUM_HEAP - _NUM_CORE_HEAP; 6217c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers if (numOtherStats != expectedNumOtherStats) { 6227c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers jniThrowExceptionFmt(env, "java/lang/RuntimeException", 6237c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers "android.os.Debug.Meminfo.NUM_OTHER_STATS=%d expected %d", 6247c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers numOtherStats, expectedNumOtherStats); 6257c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers return JNI_ERR; 6267c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers } 6277c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 6287c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers otherStats_field = env->GetFieldID(clazz, "otherStats", "[I"); 6297c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 6300e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn for (int i=0; i<_NUM_CORE_HEAP; i++) { 6310e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stat_fields[i].pss_field = 6320e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->GetFieldID(clazz, stat_field_names[i].pss_name, "I"); 6330e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stat_fields[i].privateDirty_field = 6340e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->GetFieldID(clazz, stat_field_names[i].privateDirty_name, "I"); 6350e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stat_fields[i].sharedDirty_field = 6360e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->GetFieldID(clazz, stat_field_names[i].sharedDirty_name, "I"); 6370e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 6380e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return jniRegisterNativeMethods(env, "android/os/Debug", gMethods, NELEM(gMethods)); 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 64206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden}; // namespace android 643