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, 460e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_CURSOR, 470e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_ASHMEM, 480e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_UNKNOWN_DEV, 490e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_SO, 500e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_JAR, 510e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_APK, 520e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_TTF, 530e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_DEX, 540e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_UNKNOWN_MAP, 550e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 560e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn _NUM_HEAP, 570e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn _NUM_CORE_HEAP = HEAP_NATIVE+1 580e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn}; 590e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 600e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackbornstruct stat_fields { 610e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn jfieldID pss_field; 620e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn jfieldID privateDirty_field; 630e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn jfieldID sharedDirty_field; 640e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn}; 650e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 660e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackbornstruct stat_field_names { 670e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn const char* pss_name; 680e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn const char* privateDirty_name; 690e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn const char* sharedDirty_name; 700e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn}; 710e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 720e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackbornstatic stat_fields stat_fields[_NUM_CORE_HEAP]; 730e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 740e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackbornstatic stat_field_names stat_field_names[_NUM_CORE_HEAP] = { 750e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn { "otherPss", "otherPrivateDirty", "otherSharedDirty" }, 760e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn { "dalvikPss", "dalvikPrivateDirty", "dalvikSharedDirty" }, 770e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn { "nativePss", "nativePrivateDirty", "nativeSharedDirty" } 780e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn}; 790e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 800e3328fbdd3845b0e2bec364e951498eaee6b079Dianne HackbornjfieldID otherStats_field; 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct stats_t { 830e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int pss; 840e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int privateDirty; 850e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int sharedDirty; 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define BINDER_STATS "/proc/binder/stats" 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jlong android_os_Debug_getNativeHeapSize(JNIEnv *env, jobject clazz) 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_MALLOC_H 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct mallinfo info = mallinfo(); 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jlong) info.usmblks; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jlong android_os_Debug_getNativeHeapAllocatedSize(JNIEnv *env, jobject clazz) 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_MALLOC_H 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct mallinfo info = mallinfo(); 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jlong) info.uordblks; 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jlong android_os_Debug_getNativeHeapFreeSize(JNIEnv *env, jobject clazz) 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_MALLOC_H 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct mallinfo info = mallinfo(); 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jlong) info.fordblks; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void read_mapinfo(FILE *fp, stats_t* stats) 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char line[1024]; 1230e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int len, nameLen; 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool skip, done = false; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1260e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn unsigned size = 0, resident = 0, pss = 0; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned shared_clean = 0, shared_dirty = 0; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned private_clean = 0, private_dirty = 0; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned referenced = 0; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned temp; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1320e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn unsigned long int start; 1330e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn unsigned long int end = 0; 1340e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn unsigned long int prevEnd = 0; 1350e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn char* name; 1360e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int name_pos; 1370e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 1380e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int whichHeap = HEAP_UNKNOWN; 1390e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int prevHeap = HEAP_UNKNOWN; 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1410e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn if(fgets(line, sizeof(line), fp) == 0) return; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (!done) { 1440e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn prevHeap = whichHeap; 1450e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn prevEnd = end; 1460e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_UNKNOWN; 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project skip = false; 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len = strlen(line); 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len < 1) return; 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project line[--len] = 0; 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1530e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn if (sscanf(line, "%lx-%lx %*s %*x %*x:%*x %*d%n", &start, &end, &name_pos) != 2) { 1540e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn skip = true; 1550e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else { 1560e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn while (isspace(line[name_pos])) { 1570e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn name_pos += 1; 1580e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 1590e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn name = line + name_pos; 1600e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn nameLen = strlen(name); 1610e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 1620e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn if (strstr(name, "[heap]") == name) { 1630e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_NATIVE; 1640e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (strstr(name, "/dev/ashmem/dalvik-") == name) { 1650e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_DALVIK; 1660e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (strstr(name, "/dev/ashmem/CursorWindow") == name) { 1670e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_CURSOR; 1680e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (strstr(name, "/dev/ashmem/") == name) { 1690e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_ASHMEM; 1700e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (strstr(name, "/dev/") == name) { 1710e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_UNKNOWN_DEV; 1720e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (nameLen > 3 && strcmp(name+nameLen-3, ".so") == 0) { 1730e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_SO; 1740e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (nameLen > 4 && strcmp(name+nameLen-4, ".jar") == 0) { 1750e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_JAR; 1760e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (nameLen > 4 && strcmp(name+nameLen-4, ".apk") == 0) { 1770e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_APK; 1780e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (nameLen > 4 && strcmp(name+nameLen-4, ".ttf") == 0) { 1790e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_TTF; 1800e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (nameLen > 4 && strcmp(name+nameLen-4, ".dex") == 0) { 1810e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_DEX; 1820e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (nameLen > 0) { 1830e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_UNKNOWN_MAP; 1840e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (start == prevEnd && prevHeap == HEAP_SO) { 1850e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn // bss section of a shared library. 1860e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_SO; 1870e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1906215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("native=%d dalvik=%d sqlite=%d: %s\n", isNativeHeap, isDalvikHeap, 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // isSqliteHeap, line); 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (true) { 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fgets(line, 1024, fp) == 0) { 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project done = true; 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sscanf(line, "Size: %d kB", &temp) == 1) { 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size = temp; 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (sscanf(line, "Rss: %d kB", &temp) == 1) { 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resident = temp; 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (sscanf(line, "Pss: %d kB", &temp) == 1) { 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pss = temp; 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (sscanf(line, "Shared_Clean: %d kB", &temp) == 1) { 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shared_clean = temp; 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (sscanf(line, "Shared_Dirty: %d kB", &temp) == 1) { 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shared_dirty = temp; 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (sscanf(line, "Private_Clean: %d kB", &temp) == 1) { 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private_clean = temp; 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (sscanf(line, "Private_Dirty: %d kB", &temp) == 1) { 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private_dirty = temp; 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (sscanf(line, "Referenced: %d kB", &temp) == 1) { 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project referenced = temp; 215bd51116a5310683f70a37110bf735252dc7e4e38Grace Kloba } else if (strlen(line) > 30 && line[8] == '-' && line[17] == ' ') { 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // looks like a new mapping 217bd51116a5310683f70a37110bf735252dc7e4e38Grace Kloba // example: "10000000-10001000 ---p 10000000 00:00 0" 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!skip) { 2230e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats[whichHeap].pss += pss; 2240e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats[whichHeap].privateDirty += private_dirty; 2250e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats[whichHeap].sharedDirty += shared_dirty; 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void load_maps(int pid, stats_t* stats) 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char tmp[128]; 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FILE *fp; 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sprintf(tmp, "/proc/%d/smaps", pid); 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fp = fopen(tmp, "r"); 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fp == 0) return; 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project read_mapinfo(fp, stats); 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fclose(fp); 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2433025ef332c29e255388f74b2afefe05f64bce07cDianne Hackbornstatic void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, 2443025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn jint pid, jobject object) 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2460e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats_t stats[_NUM_HEAP]; 2470e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn memset(&stats, 0, sizeof(stats)); 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2490e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn load_maps(pid, stats); 2500e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 2510e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn for (int i=_NUM_CORE_HEAP; i<_NUM_HEAP; i++) { 2520e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats[HEAP_UNKNOWN].pss += stats[i].pss; 2530e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats[HEAP_UNKNOWN].privateDirty += stats[i].privateDirty; 2540e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats[HEAP_UNKNOWN].sharedDirty += stats[i].sharedDirty; 2550e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2570e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn for (int i=0; i<_NUM_CORE_HEAP; i++) { 2580e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->SetIntField(object, stat_fields[i].pss_field, stats[i].pss); 2590e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->SetIntField(object, stat_fields[i].privateDirty_field, stats[i].privateDirty); 2600e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->SetIntField(object, stat_fields[i].sharedDirty_field, stats[i].sharedDirty); 2610e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2630e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn jintArray otherIntArray = (jintArray)env->GetObjectField(object, otherStats_field); 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2650e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn jint* otherArray = (jint*)env->GetPrimitiveArrayCritical(otherIntArray, 0); 2660e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn if (otherArray == NULL) { 2670e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn return; 2680e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 2690e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 2700e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int j=0; 2710e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn for (int i=_NUM_CORE_HEAP; i<_NUM_HEAP; i++) { 2720e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn otherArray[j++] = stats[i].pss; 2730e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn otherArray[j++] = stats[i].privateDirty; 2740e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn otherArray[j++] = stats[i].sharedDirty; 2750e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 2760e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 2770e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->ReleasePrimitiveArrayCritical(otherIntArray, otherArray, 0); 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2803025ef332c29e255388f74b2afefe05f64bce07cDianne Hackbornstatic void android_os_Debug_getDirtyPages(JNIEnv *env, jobject clazz, jobject object) 2813025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn{ 2823025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn android_os_Debug_getDirtyPagesPid(env, clazz, getpid(), object); 2833025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn} 2843025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn 285b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackbornstatic jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid) 286b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn{ 287b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn char line[1024]; 288b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn jlong pss = 0; 289b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn unsigned temp; 290b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 291b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn char tmp[128]; 292b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn FILE *fp; 293b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 294b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn sprintf(tmp, "/proc/%d/smaps", pid); 295b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn fp = fopen(tmp, "r"); 296b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn if (fp == 0) return 0; 297b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 298b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn while (true) { 299b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn if (fgets(line, 1024, fp) == 0) { 300b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn break; 301b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn } 302b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 303b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn if (sscanf(line, "Pss: %d kB", &temp) == 1) { 304b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn pss += temp; 305b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn } 306b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn } 307b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 308b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn fclose(fp); 309b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 310b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn return pss; 311b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn} 312b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 313b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackbornstatic jlong android_os_Debug_getPss(JNIEnv *env, jobject clazz) 314b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn{ 315b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn return android_os_Debug_getPssPid(env, clazz, getpid()); 316b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn} 317b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint read_binder_stat(const char* stat) 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FILE* fp = fopen(BINDER_STATS, "r"); 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fp == NULL) { 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char line[1024]; 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char compare[128]; 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int len = snprintf(compare, 128, "proc %d", getpid()); 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // loop until we have the block that represents this process 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fgets(line, 1024, fp) == 0) { 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (strncmp(compare, line, len)); 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // now that we have this process, read until we find the stat that we are looking for 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len = snprintf(compare, 128, " %s: ", stat); 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fgets(line, 1024, fp) == 0) { 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (strncmp(compare, line, len)); 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we have the line, now increment the line ptr to the value 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char* ptr = line + len; 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return atoi(ptr); 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_os_Debug_getBinderSentTransactions(JNIEnv *env, jobject clazz) 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return read_binder_stat("bcTRANSACTION"); 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_os_getBinderReceivedTransactions(JNIEnv *env, jobject clazz) 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return read_binder_stat("brTRANSACTION"); 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// these are implemented in android_util_Binder.cpp 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz); 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz); 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz); 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 36606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 36706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden/* pulled out of bionic */ 36806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFaddenextern "C" void get_malloc_leak_info(uint8_t** info, size_t* overallSize, 36906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t* infoSize, size_t* totalMemory, size_t* backtraceSize); 37006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFaddenextern "C" void free_malloc_leak_info(uint8_t* info); 37106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden#define SIZE_FLAG_ZYGOTE_CHILD (1<<31) 37206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden#define BACKTRACE_SIZE 32 37306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 37406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden/* 37506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * This is a qsort() callback. 37606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * 37706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * See dumpNativeHeap() for comments about the data format and sort order. 37806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden */ 37906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFaddenstatic int compareHeapRecords(const void* vrec1, const void* vrec2) 38006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden{ 38106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden const size_t* rec1 = (const size_t*) vrec1; 38206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden const size_t* rec2 = (const size_t*) vrec2; 38306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t size1 = *rec1; 38406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t size2 = *rec2; 38506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 38606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (size1 < size2) { 38706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return 1; 38806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } else if (size1 > size2) { 38906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return -1; 39006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 39106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 39206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden intptr_t* bt1 = (intptr_t*)(rec1 + 2); 39306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden intptr_t* bt2 = (intptr_t*)(rec2 + 2); 39406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden for (size_t idx = 0; idx < BACKTRACE_SIZE; idx++) { 39506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden intptr_t addr1 = bt1[idx]; 39606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden intptr_t addr2 = bt2[idx]; 39706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (addr1 == addr2) { 39806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (addr1 == 0) 39906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden break; 40006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden continue; 40106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 40206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (addr1 < addr2) { 40306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return -1; 40406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } else if (addr1 > addr2) { 40506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return 1; 40606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 40706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 40806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 40906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return 0; 41006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden} 41106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 41206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden/* 41306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * The get_malloc_leak_info() call returns an array of structs that 41406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * look like this: 41506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * 41606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * size_t size 41706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * size_t allocations 41806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * intptr_t backtrace[32] 41906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * 42006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * "size" is the size of the allocation, "backtrace" is a fixed-size 42106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * array of function pointers, and "allocations" is the number of 42206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * allocations with the exact same size and backtrace. 42306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * 42406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * The entries are sorted by descending total size (i.e. size*allocations) 42506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * then allocation count. For best results with "diff" we'd like to sort 42606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * primarily by individual size then stack trace. Since the entries are 42706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * fixed-size, and we're allowed (by the current implementation) to mangle 42806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * them, we can do this in place. 42906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden */ 43006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFaddenstatic void dumpNativeHeap(FILE* fp) 43106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden{ 43206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden uint8_t* info = NULL; 43306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t overallSize, infoSize, totalMemory, backtraceSize; 43406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 43506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden get_malloc_leak_info(&info, &overallSize, &infoSize, &totalMemory, 43606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden &backtraceSize); 43706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (info == NULL) { 43806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "Native heap dump not available. To enable, run these" 43906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden " commands (requires root):\n"); 44006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "$ adb shell setprop libc.debug.malloc 1\n"); 44106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "$ adb shell stop\n"); 44206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "$ adb shell start\n"); 44306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return; 44406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 44506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden assert(infoSize != 0); 44606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden assert(overallSize % infoSize == 0); 44706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 44806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "Android Native Heap Dump v1.0\n\n"); 44906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 45006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t recordCount = overallSize / infoSize; 45106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "Total memory: %zu\n", totalMemory); 45206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "Allocation records: %zd\n", recordCount); 45306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (backtraceSize != BACKTRACE_SIZE) { 45406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "WARNING: mismatched backtrace sizes (%d vs. %d)\n", 45506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden backtraceSize, BACKTRACE_SIZE); 45606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 45706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "\n"); 45806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 45906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden /* re-sort the entries */ 46006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden qsort(info, recordCount, infoSize, compareHeapRecords); 46106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 46206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden /* dump the entries to the file */ 46306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden const uint8_t* ptr = info; 46406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden for (size_t idx = 0; idx < recordCount; idx++) { 46506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t size = *(size_t*) ptr; 46606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t allocations = *(size_t*) (ptr + sizeof(size_t)); 46706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden intptr_t* backtrace = (intptr_t*) (ptr + sizeof(size_t) * 2); 46806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 46906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "z %d sz %8zu num %4zu bt", 47006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden (size & SIZE_FLAG_ZYGOTE_CHILD) != 0, 47106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size & ~SIZE_FLAG_ZYGOTE_CHILD, 47206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden allocations); 47306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden for (size_t bt = 0; bt < backtraceSize; bt++) { 47406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (backtrace[bt] == 0) { 47506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden break; 47606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } else { 47706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, " %08x", backtrace[bt]); 47806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 47906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 48006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "\n"); 48106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 48206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden ptr += infoSize; 48306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 48406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 48506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden free_malloc_leak_info(info); 486393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom 487393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom fprintf(fp, "MAPS\n"); 488393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom const char* maps = "/proc/self/maps"; 489393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom FILE* in = fopen(maps, "r"); 490393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom if (in == NULL) { 491393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom fprintf(fp, "Could not open %s\n", maps); 492393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom return; 493393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom } 494393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom char buf[BUFSIZ]; 495393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom while (size_t n = fread(buf, sizeof(char), BUFSIZ, in)) { 496393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom fwrite(buf, sizeof(char), n, fp); 497393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom } 498393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom fclose(in); 499393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom 500393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom fprintf(fp, "END\n"); 50106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden} 50206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 50306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden/* 50406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * Dump the native heap, writing human-readable output to the specified 50506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * file descriptor. 50606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden */ 50706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFaddenstatic void android_os_Debug_dumpNativeHeap(JNIEnv* env, jobject clazz, 50806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden jobject fileDescriptor) 50906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden{ 51006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (fileDescriptor == NULL) { 51106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden jniThrowNullPointerException(env, NULL); 51206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return; 51306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 51406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden int origFd = jniGetFDFromFileDescriptor(env, fileDescriptor); 51506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (origFd < 0) { 51606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden jniThrowRuntimeException(env, "Invalid file descriptor"); 51706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return; 51806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 51906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 52006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden /* dup() the descriptor so we don't close the original with fclose() */ 52106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden int fd = dup(origFd); 52206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (fd < 0) { 5238564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("dup(%d) failed: %s\n", origFd, strerror(errno)); 52406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden jniThrowRuntimeException(env, "dup() failed"); 52506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return; 52606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 52706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 52806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden FILE* fp = fdopen(fd, "w"); 52906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (fp == NULL) { 5308564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("fdopen(%d) failed: %s\n", fd, strerror(errno)); 53106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden close(fd); 53206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden jniThrowRuntimeException(env, "fdopen() failed"); 53306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return; 53406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 53506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 5365baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("Native heap dump starting...\n"); 53706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden dumpNativeHeap(fp); 5385baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("Native heap dump complete.\n"); 53906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 54006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fclose(fp); 54106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden} 54206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 54306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 544f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackbornstatic void android_os_Debug_dumpNativeBacktraceToFile(JNIEnv* env, jobject clazz, 545f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn jint pid, jstring fileName) 546f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn{ 547f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn if (fileName == NULL) { 548f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn jniThrowNullPointerException(env, NULL); 549f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn return; 550f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn } 551f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn const jchar* str = env->GetStringCritical(fileName, 0); 552f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn String8 fileName8; 553f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn if (str) { 554f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn fileName8 = String8(str, env->GetStringLength(fileName)); 555f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn env->ReleaseStringCritical(fileName, str); 556f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn } 557f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn 558f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn int fd = open(fileName8.string(), O_CREAT | O_WRONLY | O_NOFOLLOW, 0666); /* -rw-rw-rw- */ 559f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn if (fd < 0) { 560f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn fprintf(stderr, "Can't open %s: %s\n", fileName8.string(), strerror(errno)); 561f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn return; 562f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn } 563f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn 564f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn if (lseek(fd, 0, SEEK_END) < 0) { 565f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn fprintf(stderr, "lseek: %s\n", strerror(errno)); 566f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn } else { 567f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn dump_backtrace_to_file(pid, fd); 568f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn } 569f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn 570f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn close(fd); 571f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn} 572f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * JNI registration. 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gMethods[] = { 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getNativeHeapSize", "()J", 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_os_Debug_getNativeHeapSize }, 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getNativeHeapAllocatedSize", "()J", 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_os_Debug_getNativeHeapAllocatedSize }, 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getNativeHeapFreeSize", "()J", 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_os_Debug_getNativeHeapFreeSize }, 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getMemoryInfo", "(Landroid/os/Debug$MemoryInfo;)V", 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_os_Debug_getDirtyPages }, 5863025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn { "getMemoryInfo", "(ILandroid/os/Debug$MemoryInfo;)V", 5873025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn (void*) android_os_Debug_getDirtyPagesPid }, 588b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn { "getPss", "()J", 589b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn (void*) android_os_Debug_getPss }, 590b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn { "getPss", "(I)J", 591b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn (void*) android_os_Debug_getPssPid }, 59206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden { "dumpNativeHeap", "(Ljava/io/FileDescriptor;)V", 59306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden (void*) android_os_Debug_dumpNativeHeap }, 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getBinderSentTransactions", "()I", 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_os_Debug_getBinderSentTransactions }, 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getBinderReceivedTransactions", "()I", 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_os_getBinderReceivedTransactions }, 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getBinderLocalObjectCount", "()I", 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)android_os_Debug_getLocalObjectCount }, 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getBinderProxyObjectCount", "()I", 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)android_os_Debug_getProxyObjectCount }, 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getBinderDeathObjectCount", "()I", 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)android_os_Debug_getDeathObjectCount }, 604f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn { "dumpNativeBacktraceToFile", "(ILjava/lang/String;)V", 605f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn (void*)android_os_Debug_dumpNativeBacktraceToFile }, 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_os_Debug(JNIEnv *env) 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jclass clazz = env->FindClass("android/os/Debug$MemoryInfo"); 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6120e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn for (int i=0; i<_NUM_CORE_HEAP; i++) { 6130e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stat_fields[i].pss_field = 6140e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->GetFieldID(clazz, stat_field_names[i].pss_name, "I"); 6150e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stat_fields[i].privateDirty_field = 6160e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->GetFieldID(clazz, stat_field_names[i].privateDirty_name, "I"); 6170e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stat_fields[i].sharedDirty_field = 6180e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->GetFieldID(clazz, stat_field_names[i].sharedDirty_name, "I"); 6190e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 6200e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 6210e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn otherStats_field = env->GetFieldID(clazz, "otherStats", "[I"); 6220e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return jniRegisterNativeMethods(env, "android/os/Debug", gMethods, NELEM(gMethods)); 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 62606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden}; // namespace android 627