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" 235b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski#include <memtrack/memtrack.h> 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2587eac99a21772ae56018cb81db6966557b459554Ruben Brunk#include <cutils/log.h> 26f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn#include <fcntl.h> 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h> 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdlib.h> 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h> 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <unistd.h> 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <time.h> 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <sys/time.h> 3306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden#include <errno.h> 3406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden#include <assert.h> 350e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn#include <ctype.h> 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_MALLOC_H 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <malloc.h> 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 440e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackbornenum { 450e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_UNKNOWN, 460e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_DALVIK, 470e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_NATIVE, 4864770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn HEAP_DALVIK_OTHER, 497c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers HEAP_STACK, 500e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_CURSOR, 510e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_ASHMEM, 520e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_UNKNOWN_DEV, 530e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_SO, 540e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_JAR, 550e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_APK, 560e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_TTF, 570e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_DEX, 588884ef4fe80505bc6e41c167b67efbb93e43475dAnwar Ghuloum HEAP_OAT, 5988887d0a53f866e61a7524b0edfc95e6dde57d72Anwar Ghuloum HEAP_ART, 600e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn HEAP_UNKNOWN_MAP, 615b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski HEAP_GRAPHICS, 625b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski HEAP_GL, 635b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski HEAP_OTHER_MEMTRACK, 6464770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn 653c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum HEAP_DALVIK_NORMAL, 663c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum HEAP_DALVIK_LARGE, 673c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum HEAP_DALVIK_LINEARALLOC, 683c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum HEAP_DALVIK_ACCOUNTING, 693c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum HEAP_DALVIK_CODE_CACHE, 700e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 710e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn _NUM_HEAP, 725b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski _NUM_EXCLUSIVE_HEAP = HEAP_OTHER_MEMTRACK+1, 730e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn _NUM_CORE_HEAP = HEAP_NATIVE+1 740e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn}; 750e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 760e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackbornstruct stat_fields { 770e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn jfieldID pss_field; 783c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum jfieldID pssSwappable_field; 790e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn jfieldID privateDirty_field; 800e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn jfieldID sharedDirty_field; 813c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum jfieldID privateClean_field; 823a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum jfieldID sharedClean_field; 838883ced18ac25199330843964634fdf70647a127Dianne Hackborn jfieldID swappedOut_field; 840e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn}; 850e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 860e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackbornstruct stat_field_names { 870e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn const char* pss_name; 883c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum const char* pssSwappable_name; 890e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn const char* privateDirty_name; 900e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn const char* sharedDirty_name; 913c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum const char* privateClean_name; 923a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum const char* sharedClean_name; 938883ced18ac25199330843964634fdf70647a127Dianne Hackborn const char* swappedOut_name; 940e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn}; 950e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 960e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackbornstatic stat_fields stat_fields[_NUM_CORE_HEAP]; 970e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 980e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackbornstatic stat_field_names stat_field_names[_NUM_CORE_HEAP] = { 998883ced18ac25199330843964634fdf70647a127Dianne Hackborn { "otherPss", "otherSwappablePss", "otherPrivateDirty", "otherSharedDirty", 1008883ced18ac25199330843964634fdf70647a127Dianne Hackborn "otherPrivateClean", "otherSharedClean", "otherSwappedOut" }, 1018883ced18ac25199330843964634fdf70647a127Dianne Hackborn { "dalvikPss", "dalvikSwappablePss", "dalvikPrivateDirty", "dalvikSharedDirty", 1028883ced18ac25199330843964634fdf70647a127Dianne Hackborn "dalvikPrivateClean", "dalvikSharedClean", "dalvikSwappedOut" }, 1038883ced18ac25199330843964634fdf70647a127Dianne Hackborn { "nativePss", "nativeSwappablePss", "nativePrivateDirty", "nativeSharedDirty", 1048883ced18ac25199330843964634fdf70647a127Dianne Hackborn "nativePrivateClean", "nativeSharedClean", "nativeSwappedOut" } 1050e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn}; 1060e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 1070e3328fbdd3845b0e2bec364e951498eaee6b079Dianne HackbornjfieldID otherStats_field; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1095b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinskistatic bool memtrackLoaded; 1105b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstruct stats_t { 1120e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int pss; 1133c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum int swappablePss; 1140e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int privateDirty; 1150e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int sharedDirty; 1163c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum int privateClean; 1173a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum int sharedClean; 1188883ced18ac25199330843964634fdf70647a127Dianne Hackborn int swappedOut; 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define BINDER_STATS "/proc/binder/stats" 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jlong android_os_Debug_getNativeHeapSize(JNIEnv *env, jobject clazz) 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_MALLOC_H 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct mallinfo info = mallinfo(); 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jlong) info.usmblks; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jlong android_os_Debug_getNativeHeapAllocatedSize(JNIEnv *env, jobject clazz) 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_MALLOC_H 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct mallinfo info = mallinfo(); 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jlong) info.uordblks; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jlong android_os_Debug_getNativeHeapFreeSize(JNIEnv *env, jobject clazz) 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1457c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers#ifdef HAVE_MALLOC_H 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct mallinfo info = mallinfo(); 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return (jlong) info.fordblks; 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1535b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski// Container used to retrieve graphics memory pss 1545b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinskistruct graphics_memory_pss 15537c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn{ 1565b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski int graphics; 1575b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski int gl; 1585b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski int other; 1595b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski}; 16037c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn 1615b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski/* 1625b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski * Uses libmemtrack to retrieve graphics memory that the process is using. 1635b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski * Any graphics memory reported in /proc/pid/smaps is not included here. 1645b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski */ 165cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackbornstatic int read_memtrack_memory(struct memtrack_proc* p, int pid, 166cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn struct graphics_memory_pss* graphics_mem) 1675b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski{ 1685b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski int err = memtrack_proc_get(p, pid); 1695b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski if (err != 0) { 170cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn ALOGW("failed to get memory consumption info: %d", err); 1715b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski return err; 17237c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn } 17337c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn 1745b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski ssize_t pss = memtrack_proc_graphics_pss(p); 1755b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski if (pss < 0) { 176cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn ALOGW("failed to get graphics pss: %d", pss); 1775b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski return pss; 1785b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski } 1795b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski graphics_mem->graphics = pss / 1024; 18037c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn 1815b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski pss = memtrack_proc_gl_pss(p); 1825b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski if (pss < 0) { 183cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn ALOGW("failed to get gl pss: %d", pss); 1845b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski return pss; 1855b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski } 1865b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski graphics_mem->gl = pss / 1024; 18737c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn 1885b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski pss = memtrack_proc_other_pss(p); 1895b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski if (pss < 0) { 190cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn ALOGW("failed to get other pss: %d", pss); 1915b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski return pss; 1925b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski } 1935b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski graphics_mem->other = pss / 1024; 19437c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn 1955b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski return 0; 1965b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski} 19737c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn 1985b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski/* 1995b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski * Retrieves the graphics memory that is unaccounted for in /proc/pid/smaps. 2005b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski */ 2015b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinskistatic int read_memtrack_memory(int pid, struct graphics_memory_pss* graphics_mem) 2025b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski{ 2035b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski if (!memtrackLoaded) { 2045b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski return -1; 20537c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn } 20637c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn 2075b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski struct memtrack_proc* p = memtrack_proc_new(); 2085b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski if (p == NULL) { 209cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn ALOGW("failed to create memtrack_proc"); 2105b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski return -1; 2115b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski } 21237c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn 2135b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski int err = read_memtrack_memory(p, pid, graphics_mem); 2145b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski memtrack_proc_destroy(p); 2155b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski return err; 21637c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn} 21737c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void read_mapinfo(FILE *fp, stats_t* stats) 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char line[1024]; 2210e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int len, nameLen; 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool skip, done = false; 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2243c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum unsigned size = 0, resident = 0, pss = 0, swappable_pss = 0; 2253c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum float sharing_proportion = 0.0; 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned shared_clean = 0, shared_dirty = 0; 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned private_clean = 0, private_dirty = 0; 2288883ced18ac25199330843964634fdf70647a127Dianne Hackborn unsigned swapped_out = 0; 2293c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum bool is_swappable = false; 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned referenced = 0; 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned temp; 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2330e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn unsigned long int start; 2340e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn unsigned long int end = 0; 2350e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn unsigned long int prevEnd = 0; 2360e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn char* name; 2370e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int name_pos; 2380e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 2390e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int whichHeap = HEAP_UNKNOWN; 2403c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum int subHeap = HEAP_UNKNOWN; 2410e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int prevHeap = HEAP_UNKNOWN; 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2430e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn if(fgets(line, sizeof(line), fp) == 0) return; 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (!done) { 2460e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn prevHeap = whichHeap; 2470e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn prevEnd = end; 2480e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_UNKNOWN; 2493c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum subHeap = HEAP_UNKNOWN; 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project skip = false; 2513c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum is_swappable = false; 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len = strlen(line); 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (len < 1) return; 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project line[--len] = 0; 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2570e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn if (sscanf(line, "%lx-%lx %*s %*x %*x:%*x %*d%n", &start, &end, &name_pos) != 2) { 2580e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn skip = true; 2590e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else { 2600e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn while (isspace(line[name_pos])) { 2610e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn name_pos += 1; 2620e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 2630e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn name = line + name_pos; 2640e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn nameLen = strlen(name); 2650e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 26664770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn if ((strstr(name, "[heap]") == name)) { 2670e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_NATIVE; 26864770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn } else if (strncmp(name, "/dev/ashmem", 11) == 0) { 26964770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn if (strncmp(name, "/dev/ashmem/dalvik-", 19) == 0) { 27064770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn whichHeap = HEAP_DALVIK_OTHER; 27164770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn if (strstr(name, "/dev/ashmem/dalvik-LinearAlloc") == name) { 27264770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn subHeap = HEAP_DALVIK_LINEARALLOC; 27364770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn } else if ((strstr(name, "/dev/ashmem/dalvik-mark") == name) || 27464770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn (strstr(name, "/dev/ashmem/dalvik-allocspace alloc space live-bitmap") == name) || 27564770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn (strstr(name, "/dev/ashmem/dalvik-allocspace alloc space mark-bitmap") == name) || 27664770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn (strstr(name, "/dev/ashmem/dalvik-card table") == name) || 27764770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn (strstr(name, "/dev/ashmem/dalvik-allocation stack") == name) || 27864770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn (strstr(name, "/dev/ashmem/dalvik-live stack") == name) || 27964770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn (strstr(name, "/dev/ashmem/dalvik-imagespace") == name) || 28064770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn (strstr(name, "/dev/ashmem/dalvik-bitmap") == name) || 28164770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn (strstr(name, "/dev/ashmem/dalvik-card-table") == name) || 28264770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn (strstr(name, "/dev/ashmem/dalvik-mark-stack") == name) || 28364770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn (strstr(name, "/dev/ashmem/dalvik-aux-structure") == name)) { 28464770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn subHeap = HEAP_DALVIK_ACCOUNTING; 28564770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn } else if (strstr(name, "/dev/ashmem/dalvik-large") == name) { 28664770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn whichHeap = HEAP_DALVIK; 28764770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn subHeap = HEAP_DALVIK_LARGE; 28864770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn } else if (strstr(name, "/dev/ashmem/dalvik-jit-code-cache") == name) { 28964770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn subHeap = HEAP_DALVIK_CODE_CACHE; 29064770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn } else { 29164770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn // This is the regular Dalvik heap. 29264770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn whichHeap = HEAP_DALVIK; 29364770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn subHeap = HEAP_DALVIK_NORMAL; 29464770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn } 29564770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn } else if (strncmp(name, "/dev/ashmem/CursorWindow", 24) == 0) { 29664770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn whichHeap = HEAP_CURSOR; 29764770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn } else if (strncmp(name, "/dev/ashmem/libc malloc", 23) == 0) { 29864770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn whichHeap = HEAP_NATIVE; 29964770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn } else { 30064770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn whichHeap = HEAP_ASHMEM; 30164770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn } 302cb4728f247e3793e7fc1baa031290aa732bb77a7Colin Cross } else if (strncmp(name, "[anon:libc_malloc]", 18) == 0) { 303cb4728f247e3793e7fc1baa031290aa732bb77a7Colin Cross whichHeap = HEAP_NATIVE; 30464770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn } else if (strncmp(name, "[stack", 6) == 0) { 3057c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers whichHeap = HEAP_STACK; 30664770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn } else if (strncmp(name, "/dev/", 5) == 0) { 3070e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_UNKNOWN_DEV; 3080e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (nameLen > 3 && strcmp(name+nameLen-3, ".so") == 0) { 3090e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_SO; 3103c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum is_swappable = true; 3110e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (nameLen > 4 && strcmp(name+nameLen-4, ".jar") == 0) { 3120e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_JAR; 3133c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum is_swappable = true; 3140e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (nameLen > 4 && strcmp(name+nameLen-4, ".apk") == 0) { 3150e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_APK; 3163c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum is_swappable = true; 3170e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (nameLen > 4 && strcmp(name+nameLen-4, ".ttf") == 0) { 3180e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_TTF; 3193c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum is_swappable = true; 3209f8589c31f8910a9c3c33a81675822da9f0cf2dfIan Rogers } else if ((nameLen > 4 && strcmp(name+nameLen-4, ".dex") == 0) || 3219f8589c31f8910a9c3c33a81675822da9f0cf2dfIan Rogers (nameLen > 5 && strcmp(name+nameLen-5, ".odex") == 0)) { 3220e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_DEX; 3233c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum is_swappable = true; 3248884ef4fe80505bc6e41c167b67efbb93e43475dAnwar Ghuloum } else if (nameLen > 4 && strcmp(name+nameLen-4, ".oat") == 0) { 3258884ef4fe80505bc6e41c167b67efbb93e43475dAnwar Ghuloum whichHeap = HEAP_OAT; 3263c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum is_swappable = true; 32788887d0a53f866e61a7524b0edfc95e6dde57d72Anwar Ghuloum } else if (nameLen > 4 && strcmp(name+nameLen-4, ".art") == 0) { 32888887d0a53f866e61a7524b0edfc95e6dde57d72Anwar Ghuloum whichHeap = HEAP_ART; 3293c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum is_swappable = true; 330cb4728f247e3793e7fc1baa031290aa732bb77a7Colin Cross } else if (strncmp(name, "[anon:", 6) == 0) { 331cb4728f247e3793e7fc1baa031290aa732bb77a7Colin Cross whichHeap = HEAP_UNKNOWN; 3320e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (nameLen > 0) { 3330e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_UNKNOWN_MAP; 3340e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } else if (start == prevEnd && prevHeap == HEAP_SO) { 3350e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn // bss section of a shared library. 3360e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn whichHeap = HEAP_SO; 3370e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3406215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("native=%d dalvik=%d sqlite=%d: %s\n", isNativeHeap, isDalvikHeap, 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // isSqliteHeap, line); 3427c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 3438883ced18ac25199330843964634fdf70647a127Dianne Hackborn shared_clean = 0; 3448883ced18ac25199330843964634fdf70647a127Dianne Hackborn shared_dirty = 0; 3458883ced18ac25199330843964634fdf70647a127Dianne Hackborn private_clean = 0; 3468883ced18ac25199330843964634fdf70647a127Dianne Hackborn private_dirty = 0; 3478883ced18ac25199330843964634fdf70647a127Dianne Hackborn swapped_out = 0; 3488883ced18ac25199330843964634fdf70647a127Dianne Hackborn 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (true) { 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fgets(line, 1024, fp) == 0) { 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project done = true; 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3558883ced18ac25199330843964634fdf70647a127Dianne Hackborn if (line[0] == 'S' && sscanf(line, "Size: %d kB", &temp) == 1) { 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size = temp; 3578883ced18ac25199330843964634fdf70647a127Dianne Hackborn } else if (line[0] == 'R' && sscanf(line, "Rss: %d kB", &temp) == 1) { 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project resident = temp; 3598883ced18ac25199330843964634fdf70647a127Dianne Hackborn } else if (line[0] == 'P' && sscanf(line, "Pss: %d kB", &temp) == 1) { 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project pss = temp; 3618883ced18ac25199330843964634fdf70647a127Dianne Hackborn } else if (line[0] == 'S' && sscanf(line, "Shared_Clean: %d kB", &temp) == 1) { 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shared_clean = temp; 3638883ced18ac25199330843964634fdf70647a127Dianne Hackborn } else if (line[0] == 'S' && sscanf(line, "Shared_Dirty: %d kB", &temp) == 1) { 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project shared_dirty = temp; 3658883ced18ac25199330843964634fdf70647a127Dianne Hackborn } else if (line[0] == 'P' && sscanf(line, "Private_Clean: %d kB", &temp) == 1) { 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private_clean = temp; 3678883ced18ac25199330843964634fdf70647a127Dianne Hackborn } else if (line[0] == 'P' && sscanf(line, "Private_Dirty: %d kB", &temp) == 1) { 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private_dirty = temp; 3698883ced18ac25199330843964634fdf70647a127Dianne Hackborn } else if (line[0] == 'R' && sscanf(line, "Referenced: %d kB", &temp) == 1) { 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project referenced = temp; 3718883ced18ac25199330843964634fdf70647a127Dianne Hackborn } else if (line[0] == 'S' && sscanf(line, "Swap: %d kB", &temp) == 1) { 3728883ced18ac25199330843964634fdf70647a127Dianne Hackborn swapped_out = temp; 373bd51116a5310683f70a37110bf735252dc7e4e38Grace Kloba } else if (strlen(line) > 30 && line[8] == '-' && line[17] == ' ') { 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // looks like a new mapping 375bd51116a5310683f70a37110bf735252dc7e4e38Grace Kloba // example: "10000000-10001000 ---p 10000000 00:00 0" 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!skip) { 3813c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum if (is_swappable && (pss > 0)) { 3823c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum sharing_proportion = 0.0; 3833c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum if ((shared_clean > 0) || (shared_dirty > 0)) { 3848883ced18ac25199330843964634fdf70647a127Dianne Hackborn sharing_proportion = (pss - private_clean 3858883ced18ac25199330843964634fdf70647a127Dianne Hackborn - private_dirty)/(shared_clean+shared_dirty); 3863c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum } 3873c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum swappable_pss = (sharing_proportion*shared_clean) + private_clean; 3883c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum } else 3893c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum swappable_pss = 0; 3903c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum 3910e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats[whichHeap].pss += pss; 3923c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum stats[whichHeap].swappablePss += swappable_pss; 3930e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats[whichHeap].privateDirty += private_dirty; 3940e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats[whichHeap].sharedDirty += shared_dirty; 3953c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum stats[whichHeap].privateClean += private_clean; 3963a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum stats[whichHeap].sharedClean += shared_clean; 3978883ced18ac25199330843964634fdf70647a127Dianne Hackborn stats[whichHeap].swappedOut += swapped_out; 39864770d16b0907a8e1ee81ef6c8fa398a6bdbee79Dianne Hackborn if (whichHeap == HEAP_DALVIK || whichHeap == HEAP_DALVIK_OTHER) { 3993c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum stats[subHeap].pss += pss; 4003c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum stats[subHeap].swappablePss += swappable_pss; 4013c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum stats[subHeap].privateDirty += private_dirty; 4023c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum stats[subHeap].sharedDirty += shared_dirty; 4033c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum stats[subHeap].privateClean += private_clean; 4043c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum stats[subHeap].sharedClean += shared_clean; 4058883ced18ac25199330843964634fdf70647a127Dianne Hackborn stats[subHeap].swappedOut += swapped_out; 4063c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum } 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic void load_maps(int pid, stats_t* stats) 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char tmp[128]; 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FILE *fp; 4157c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sprintf(tmp, "/proc/%d/smaps", pid); 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fp = fopen(tmp, "r"); 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fp == 0) return; 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project read_mapinfo(fp, stats); 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project fclose(fp); 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4243025ef332c29e255388f74b2afefe05f64bce07cDianne Hackbornstatic void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, 4253025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn jint pid, jobject object) 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4270e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats_t stats[_NUM_HEAP]; 4280e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn memset(&stats, 0, sizeof(stats)); 4297c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 4300e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn load_maps(pid, stats); 4310e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 4325b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski struct graphics_memory_pss graphics_mem; 4335b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski if (read_memtrack_memory(pid, &graphics_mem) == 0) { 4345b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski stats[HEAP_GRAPHICS].pss = graphics_mem.graphics; 4355b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski stats[HEAP_GRAPHICS].privateDirty = graphics_mem.graphics; 4365b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski stats[HEAP_GL].pss = graphics_mem.gl; 4375b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski stats[HEAP_GL].privateDirty = graphics_mem.gl; 4385b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski stats[HEAP_OTHER_MEMTRACK].pss = graphics_mem.other; 4395b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski stats[HEAP_OTHER_MEMTRACK].privateDirty = graphics_mem.other; 4405b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski } 44137c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn 4423c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum for (int i=_NUM_CORE_HEAP; i<_NUM_EXCLUSIVE_HEAP; i++) { 4430e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats[HEAP_UNKNOWN].pss += stats[i].pss; 4443c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum stats[HEAP_UNKNOWN].swappablePss += stats[i].swappablePss; 4450e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats[HEAP_UNKNOWN].privateDirty += stats[i].privateDirty; 4460e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stats[HEAP_UNKNOWN].sharedDirty += stats[i].sharedDirty; 4473c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum stats[HEAP_UNKNOWN].privateClean += stats[i].privateClean; 4483a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum stats[HEAP_UNKNOWN].sharedClean += stats[i].sharedClean; 4498883ced18ac25199330843964634fdf70647a127Dianne Hackborn stats[HEAP_UNKNOWN].swappedOut += stats[i].swappedOut; 4500e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4520e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn for (int i=0; i<_NUM_CORE_HEAP; i++) { 4530e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->SetIntField(object, stat_fields[i].pss_field, stats[i].pss); 4543c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum env->SetIntField(object, stat_fields[i].pssSwappable_field, stats[i].swappablePss); 4550e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->SetIntField(object, stat_fields[i].privateDirty_field, stats[i].privateDirty); 4560e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->SetIntField(object, stat_fields[i].sharedDirty_field, stats[i].sharedDirty); 4573c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum env->SetIntField(object, stat_fields[i].privateClean_field, stats[i].privateClean); 4583a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum env->SetIntField(object, stat_fields[i].sharedClean_field, stats[i].sharedClean); 4598883ced18ac25199330843964634fdf70647a127Dianne Hackborn env->SetIntField(object, stat_fields[i].swappedOut_field, stats[i].swappedOut); 4600e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 4617c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 4623c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum 4630e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn jintArray otherIntArray = (jintArray)env->GetObjectField(object, otherStats_field); 4647c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 4650e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn jint* otherArray = (jint*)env->GetPrimitiveArrayCritical(otherIntArray, 0); 4660e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn if (otherArray == NULL) { 4670e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn return; 4680e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 4690e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 4700e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn int j=0; 4710e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn for (int i=_NUM_CORE_HEAP; i<_NUM_HEAP; i++) { 4720e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn otherArray[j++] = stats[i].pss; 4733c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum otherArray[j++] = stats[i].swappablePss; 4740e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn otherArray[j++] = stats[i].privateDirty; 4750e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn otherArray[j++] = stats[i].sharedDirty; 4763c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum otherArray[j++] = stats[i].privateClean; 4773a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum otherArray[j++] = stats[i].sharedClean; 4788883ced18ac25199330843964634fdf70647a127Dianne Hackborn otherArray[j++] = stats[i].swappedOut; 4790e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 4800e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 4810e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->ReleasePrimitiveArrayCritical(otherIntArray, otherArray, 0); 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4843025ef332c29e255388f74b2afefe05f64bce07cDianne Hackbornstatic void android_os_Debug_getDirtyPages(JNIEnv *env, jobject clazz, jobject object) 4853025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn{ 4863025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn android_os_Debug_getDirtyPagesPid(env, clazz, getpid(), object); 4873025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn} 4883025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn 489c8230519728b14065effd3b7d4eca273ff86160cDianne Hackbornstatic jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid, jlongArray outUss) 490b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn{ 491b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn char line[1024]; 492b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn jlong pss = 0; 493c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn jlong uss = 0; 494b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn unsigned temp; 495b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 496b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn char tmp[128]; 497b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn FILE *fp; 498b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 4995b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski struct graphics_memory_pss graphics_mem; 5005b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski if (read_memtrack_memory(pid, &graphics_mem) == 0) { 5015b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski pss = uss = graphics_mem.graphics + graphics_mem.gl + graphics_mem.other; 5025b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski } 50337c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn 504b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn sprintf(tmp, "/proc/%d/smaps", pid); 505b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn fp = fopen(tmp, "r"); 506b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 50737c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn if (fp != 0) { 50837c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn while (true) { 50937c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn if (fgets(line, 1024, fp) == NULL) { 51037c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn break; 51137c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn } 512b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 51337c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn if (line[0] == 'P') { 51437c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn if (strncmp(line, "Pss:", 4) == 0) { 51537c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn char* c = line + 4; 51637c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn while (*c != 0 && (*c < '0' || *c > '9')) { 51737c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn c++; 51837c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn } 51937c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn pss += atoi(c); 52037c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn } else if (strncmp(line, "Private_Clean:", 14) 52137c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn || strncmp(line, "Private_Dirty:", 14)) { 52237c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn char* c = line + 14; 52337c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn while (*c != 0 && (*c < '0' || *c > '9')) { 52437c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn c++; 52537c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn } 52637c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn uss += atoi(c); 527c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn } 528cfc837f7fa43362b5049f648fe1bfdf5a010cc1cDianne Hackborn } 529b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn } 530b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 53137c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn fclose(fp); 53237c99432625e2adeb50baf25f471abc8481b2b3eDianne Hackborn } 533b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 534c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn if (outUss != NULL) { 535c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn if (env->GetArrayLength(outUss) >= 1) { 536c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn jlong* outUssArray = env->GetLongArrayElements(outUss, 0); 537c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn if (outUssArray != NULL) { 538c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn outUssArray[0] = uss; 539c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn } 540c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn env->ReleaseLongArrayElements(outUss, outUssArray, 0); 541c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn } 542c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn } 543c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn 544b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn return pss; 545b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn} 546b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 547b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackbornstatic jlong android_os_Debug_getPss(JNIEnv *env, jobject clazz) 548b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn{ 549c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn return android_os_Debug_getPssPid(env, clazz, getpid(), NULL); 550b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn} 551b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn 552cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackbornenum { 553cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn MEMINFO_TOTAL, 554cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn MEMINFO_FREE, 555cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn MEMINFO_BUFFERS, 556cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn MEMINFO_CACHED, 557cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn MEMINFO_SHMEM, 558cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn MEMINFO_SLAB, 559cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn MEMINFO_SWAP_TOTAL, 560cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn MEMINFO_SWAP_FREE, 561cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn MEMINFO_ZRAM_TOTAL, 562cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn MEMINFO_COUNT 563cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn}; 564cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn 5658e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackbornstatic void android_os_Debug_getMemInfo(JNIEnv *env, jobject clazz, jlongArray out) 5668e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn{ 5678e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn char buffer[1024]; 5688e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn int numFound = 0; 5698e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 5708e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn if (out == NULL) { 5718e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn jniThrowNullPointerException(env, "out == null"); 5728e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn return; 5738e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn } 5748e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 5758e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn int fd = open("/proc/meminfo", O_RDONLY); 5768e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 5778e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn if (fd < 0) { 578cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn ALOGW("Unable to open /proc/meminfo: %s\n", strerror(errno)); 5798e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn return; 5808e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn } 5818e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 582cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn int len = read(fd, buffer, sizeof(buffer)-1); 5838e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn close(fd); 5848e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 5858e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn if (len < 0) { 586cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn ALOGW("Empty /proc/meminfo"); 5878e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn return; 5888e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn } 5898e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn buffer[len] = 0; 5908e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 5918e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn static const char* const tags[] = { 5928e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn "MemTotal:", 5938e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn "MemFree:", 5948e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn "Buffers:", 5958e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn "Cached:", 5968e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn "Shmem:", 5978e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn "Slab:", 598cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn "SwapTotal:", 599cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn "SwapFree:", 6008e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn NULL 6018e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn }; 6028e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn static const int tagsLen[] = { 6038e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 9, 6048e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 8, 6058e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 8, 6068e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 7, 6078e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 6, 6088e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 5, 609cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn 10, 610cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn 9, 6118e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 0 6128e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn }; 613cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn long mem[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 6148e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 6158e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn char* p = buffer; 616cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn while (*p && numFound < 8) { 6178e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn int i = 0; 6188e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn while (tags[i]) { 6198e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn if (strncmp(p, tags[i], tagsLen[i]) == 0) { 6208e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn p += tagsLen[i]; 6218e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn while (*p == ' ') p++; 6228e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn char* num = p; 6238e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn while (*p >= '0' && *p <= '9') p++; 6248e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn if (*p != 0) { 6258e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn *p = 0; 6268e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn p++; 6278e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn } 6288e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn mem[i] = atoll(num); 6298e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn numFound++; 6308e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn break; 6318e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn } 6328e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn i++; 6338e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn } 6348e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn while (*p && *p != '\n') { 6358e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn p++; 6368e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn } 6378e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn if (*p) p++; 6388e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn } 6398e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 640cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn fd = open("/sys/block/zram0/mem_used_total", O_RDONLY); 641cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn if (fd >= 0) { 642cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn len = read(fd, buffer, sizeof(buffer)-1); 643cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn close(fd); 644cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn if (len > 0) { 645cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn buffer[len] = 0; 646cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn mem[MEMINFO_ZRAM_TOTAL] = atoll(buffer)/1024; 647cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn } 648cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn } 649cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn 6508e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn int maxNum = env->GetArrayLength(out); 651cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn if (maxNum > MEMINFO_COUNT) { 652cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn maxNum = MEMINFO_COUNT; 653cbd9a52f256087426feb19ac6e51eff772e81375Dianne Hackborn } 6548e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn jlong* outArray = env->GetLongArrayElements(out, 0); 6558e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn if (outArray != NULL) { 656cb4285537b1bf67b5a248e509d5fe41a6f49282eDianne Hackborn for (int i=0; i<maxNum; i++) { 6578e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn outArray[i] = mem[i]; 6588e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn } 6598e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn } 6608e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn env->ReleaseLongArrayElements(out, outArray, 0); 6618e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn} 6628e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint read_binder_stat(const char* stat) 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FILE* fp = fopen(BINDER_STATS, "r"); 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fp == NULL) { 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char line[1024]; 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char compare[128]; 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int len = snprintf(compare, 128, "proc %d", getpid()); 6747c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // loop until we have the block that represents this process 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fgets(line, 1024, fp) == 0) { 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (strncmp(compare, line, len)); 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6827c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers // now that we have this process, read until we find the stat that we are looking for 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project len = snprintf(compare, 128, " %s: ", stat); 6847c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fgets(line, 1024, fp) == 0) { 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return -1; 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while (strncmp(compare, line, len)); 6907c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // we have the line, now increment the line ptr to the value 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project char* ptr = line + len; 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return atoi(ptr); 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_os_Debug_getBinderSentTransactions(JNIEnv *env, jobject clazz) 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return read_binder_stat("bcTRANSACTION"); 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic jint android_os_getBinderReceivedTransactions(JNIEnv *env, jobject clazz) 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return read_binder_stat("brTRANSACTION"); 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// these are implemented in android_util_Binder.cpp 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjint android_os_Debug_getLocalObjectCount(JNIEnv* env, jobject clazz); 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjint android_os_Debug_getProxyObjectCount(JNIEnv* env, jobject clazz); 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectjint android_os_Debug_getDeathObjectCount(JNIEnv* env, jobject clazz); 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 71106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 71206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden/* pulled out of bionic */ 71306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFaddenextern "C" void get_malloc_leak_info(uint8_t** info, size_t* overallSize, 71406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t* infoSize, size_t* totalMemory, size_t* backtraceSize); 71506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFaddenextern "C" void free_malloc_leak_info(uint8_t* info); 71606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden#define SIZE_FLAG_ZYGOTE_CHILD (1<<31) 71706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden#define BACKTRACE_SIZE 32 71806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 71906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden/* 72006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * This is a qsort() callback. 72106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * 72206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * See dumpNativeHeap() for comments about the data format and sort order. 72306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden */ 72406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFaddenstatic int compareHeapRecords(const void* vrec1, const void* vrec2) 72506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden{ 72606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden const size_t* rec1 = (const size_t*) vrec1; 72706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden const size_t* rec2 = (const size_t*) vrec2; 72806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t size1 = *rec1; 72906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t size2 = *rec2; 73006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 73106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (size1 < size2) { 73206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return 1; 73306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } else if (size1 > size2) { 73406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return -1; 73506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 73606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 73706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden intptr_t* bt1 = (intptr_t*)(rec1 + 2); 73806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden intptr_t* bt2 = (intptr_t*)(rec2 + 2); 73906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden for (size_t idx = 0; idx < BACKTRACE_SIZE; idx++) { 74006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden intptr_t addr1 = bt1[idx]; 74106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden intptr_t addr2 = bt2[idx]; 74206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (addr1 == addr2) { 74306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (addr1 == 0) 74406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden break; 74506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden continue; 74606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 74706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (addr1 < addr2) { 74806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return -1; 74906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } else if (addr1 > addr2) { 75006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return 1; 75106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 75206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 75306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 75406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return 0; 75506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden} 75606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 75706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden/* 75806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * The get_malloc_leak_info() call returns an array of structs that 75906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * look like this: 76006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * 76106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * size_t size 76206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * size_t allocations 76306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * intptr_t backtrace[32] 76406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * 76506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * "size" is the size of the allocation, "backtrace" is a fixed-size 76606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * array of function pointers, and "allocations" is the number of 76706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * allocations with the exact same size and backtrace. 76806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * 76906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * The entries are sorted by descending total size (i.e. size*allocations) 77006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * then allocation count. For best results with "diff" we'd like to sort 77106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * primarily by individual size then stack trace. Since the entries are 77206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * fixed-size, and we're allowed (by the current implementation) to mangle 77306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * them, we can do this in place. 77406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden */ 77506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFaddenstatic void dumpNativeHeap(FILE* fp) 77606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden{ 77706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden uint8_t* info = NULL; 77806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t overallSize, infoSize, totalMemory, backtraceSize; 77906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 78006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden get_malloc_leak_info(&info, &overallSize, &infoSize, &totalMemory, 78106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden &backtraceSize); 78206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (info == NULL) { 78306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "Native heap dump not available. To enable, run these" 78406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden " commands (requires root):\n"); 78506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "$ adb shell setprop libc.debug.malloc 1\n"); 78606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "$ adb shell stop\n"); 78706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "$ adb shell start\n"); 78806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return; 78906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 79006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden assert(infoSize != 0); 79106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden assert(overallSize % infoSize == 0); 79206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 79306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "Android Native Heap Dump v1.0\n\n"); 79406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 79506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t recordCount = overallSize / infoSize; 79606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "Total memory: %zu\n", totalMemory); 79706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "Allocation records: %zd\n", recordCount); 79806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (backtraceSize != BACKTRACE_SIZE) { 79906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "WARNING: mismatched backtrace sizes (%d vs. %d)\n", 80006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden backtraceSize, BACKTRACE_SIZE); 80106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 80206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "\n"); 80306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 80406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden /* re-sort the entries */ 80506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden qsort(info, recordCount, infoSize, compareHeapRecords); 80606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 80706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden /* dump the entries to the file */ 80806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden const uint8_t* ptr = info; 80906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden for (size_t idx = 0; idx < recordCount; idx++) { 81006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t size = *(size_t*) ptr; 81106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size_t allocations = *(size_t*) (ptr + sizeof(size_t)); 81206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden intptr_t* backtrace = (intptr_t*) (ptr + sizeof(size_t) * 2); 81306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 81406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "z %d sz %8zu num %4zu bt", 81506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden (size & SIZE_FLAG_ZYGOTE_CHILD) != 0, 81606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden size & ~SIZE_FLAG_ZYGOTE_CHILD, 81706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden allocations); 81806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden for (size_t bt = 0; bt < backtraceSize; bt++) { 81906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (backtrace[bt] == 0) { 82006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden break; 82106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } else { 82206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, " %08x", backtrace[bt]); 82306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 82406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 82506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fprintf(fp, "\n"); 82606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 82706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden ptr += infoSize; 82806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 82906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 83006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden free_malloc_leak_info(info); 831393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom 832393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom fprintf(fp, "MAPS\n"); 833393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom const char* maps = "/proc/self/maps"; 834393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom FILE* in = fopen(maps, "r"); 835393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom if (in == NULL) { 836393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom fprintf(fp, "Could not open %s\n", maps); 837393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom return; 838393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom } 839393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom char buf[BUFSIZ]; 840393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom while (size_t n = fread(buf, sizeof(char), BUFSIZ, in)) { 841393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom fwrite(buf, sizeof(char), n, fp); 842393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom } 843393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom fclose(in); 844393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom 845393b84c137fe52f42205cef7e63b7a04b4bfd789Brian Carlstrom fprintf(fp, "END\n"); 84606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden} 84706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 84806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden/* 84906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * Dump the native heap, writing human-readable output to the specified 85006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden * file descriptor. 85106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden */ 85206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFaddenstatic void android_os_Debug_dumpNativeHeap(JNIEnv* env, jobject clazz, 85306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden jobject fileDescriptor) 85406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden{ 85506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (fileDescriptor == NULL) { 8567c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers jniThrowNullPointerException(env, "fd == null"); 85706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return; 85806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 85906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden int origFd = jniGetFDFromFileDescriptor(env, fileDescriptor); 86006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (origFd < 0) { 86106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden jniThrowRuntimeException(env, "Invalid file descriptor"); 86206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return; 86306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 86406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 86506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden /* dup() the descriptor so we don't close the original with fclose() */ 86606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden int fd = dup(origFd); 86706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (fd < 0) { 8688564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("dup(%d) failed: %s\n", origFd, strerror(errno)); 86906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden jniThrowRuntimeException(env, "dup() failed"); 87006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return; 87106a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 87206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 87306a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden FILE* fp = fdopen(fd, "w"); 87406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden if (fp == NULL) { 8758564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("fdopen(%d) failed: %s\n", fd, strerror(errno)); 87606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden close(fd); 87706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden jniThrowRuntimeException(env, "fdopen() failed"); 87806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden return; 87906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden } 88006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 8815baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("Native heap dump starting...\n"); 88206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden dumpNativeHeap(fp); 8835baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("Native heap dump complete.\n"); 88406a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 88506a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden fclose(fp); 88606a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden} 88706a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 88806a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden 889f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackbornstatic void android_os_Debug_dumpNativeBacktraceToFile(JNIEnv* env, jobject clazz, 890f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn jint pid, jstring fileName) 891f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn{ 892f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn if (fileName == NULL) { 8937c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers jniThrowNullPointerException(env, "file == null"); 894f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn return; 895f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn } 896f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn const jchar* str = env->GetStringCritical(fileName, 0); 897f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn String8 fileName8; 898f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn if (str) { 899f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn fileName8 = String8(str, env->GetStringLength(fileName)); 900f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn env->ReleaseStringCritical(fileName, str); 901f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn } 902f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn 903f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn int fd = open(fileName8.string(), O_CREAT | O_WRONLY | O_NOFOLLOW, 0666); /* -rw-rw-rw- */ 904f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn if (fd < 0) { 905f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn fprintf(stderr, "Can't open %s: %s\n", fileName8.string(), strerror(errno)); 906f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn return; 907f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn } 908f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn 909f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn if (lseek(fd, 0, SEEK_END) < 0) { 910f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn fprintf(stderr, "lseek: %s\n", strerror(errno)); 911f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn } else { 912f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn dump_backtrace_to_file(pid, fd); 913f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn } 914f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn 915f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn close(fd); 916f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn} 917f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * JNI registration. 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatic JNINativeMethod gMethods[] = { 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getNativeHeapSize", "()J", 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_os_Debug_getNativeHeapSize }, 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getNativeHeapAllocatedSize", "()J", 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_os_Debug_getNativeHeapAllocatedSize }, 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getNativeHeapFreeSize", "()J", 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_os_Debug_getNativeHeapFreeSize }, 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getMemoryInfo", "(Landroid/os/Debug$MemoryInfo;)V", 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_os_Debug_getDirtyPages }, 9313025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn { "getMemoryInfo", "(ILandroid/os/Debug$MemoryInfo;)V", 9323025ef332c29e255388f74b2afefe05f64bce07cDianne Hackborn (void*) android_os_Debug_getDirtyPagesPid }, 933b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn { "getPss", "()J", 934b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn (void*) android_os_Debug_getPss }, 935c8230519728b14065effd3b7d4eca273ff86160cDianne Hackborn { "getPss", "(I[J)J", 936b437e090ec03a2bab10bdfcb9484577a7f34e157Dianne Hackborn (void*) android_os_Debug_getPssPid }, 9378e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn { "getMemInfo", "([J)V", 9388e69257a9c7e9c1781e1f53d8856358ada38921dDianne Hackborn (void*) android_os_Debug_getMemInfo }, 93906a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden { "dumpNativeHeap", "(Ljava/io/FileDescriptor;)V", 94006a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden (void*) android_os_Debug_dumpNativeHeap }, 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getBinderSentTransactions", "()I", 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_os_Debug_getBinderSentTransactions }, 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getBinderReceivedTransactions", "()I", 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*) android_os_getBinderReceivedTransactions }, 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getBinderLocalObjectCount", "()I", 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)android_os_Debug_getLocalObjectCount }, 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getBinderProxyObjectCount", "()I", 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)android_os_Debug_getProxyObjectCount }, 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { "getBinderDeathObjectCount", "()I", 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (void*)android_os_Debug_getDeathObjectCount }, 951f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn { "dumpNativeBacktraceToFile", "(ILjava/lang/String;)V", 952f72467ad9843bf5d4b75fb308386e77ebb5c3447Dianne Hackborn (void*)android_os_Debug_dumpNativeBacktraceToFile }, 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectint register_android_os_Debug(JNIEnv *env) 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 9575b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski int err = memtrack_init(); 9585b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski if (err != 0) { 9595b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski memtrackLoaded = false; 9605b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski ALOGE("failed to load memtrack module: %d", err); 9615b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski } else { 9625b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski memtrackLoaded = true; 9635b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski } 9645b4ef81f2b79dd5d597b1681de4d0311d46693aaAdam Lesinski 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project jclass clazz = env->FindClass("android/os/Debug$MemoryInfo"); 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9677c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers // Sanity check the number of other statistics expected in Java matches here. 9687c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers jfieldID numOtherStats_field = env->GetStaticFieldID(clazz, "NUM_OTHER_STATS", "I"); 9697c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers jint numOtherStats = env->GetStaticIntField(clazz, numOtherStats_field); 9703c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum jfieldID numDvkStats_field = env->GetStaticFieldID(clazz, "NUM_DVK_STATS", "I"); 9713c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum jint numDvkStats = env->GetStaticIntField(clazz, numDvkStats_field); 9727c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers int expectedNumOtherStats = _NUM_HEAP - _NUM_CORE_HEAP; 9733c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum if ((numOtherStats + numDvkStats) != expectedNumOtherStats) { 9747c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers jniThrowExceptionFmt(env, "java/lang/RuntimeException", 9753c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum "android.os.Debug.Meminfo.NUM_OTHER_STATS+android.os.Debug.Meminfo.NUM_DVK_STATS=%d expected %d", 9763c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum numOtherStats+numDvkStats, expectedNumOtherStats); 9777c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers return JNI_ERR; 9787c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers } 9797c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 9807c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers otherStats_field = env->GetFieldID(clazz, "otherStats", "[I"); 9817c9f30bfb361ccb864e6d130e0f4f2af53fc1c32Ian Rogers 9820e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn for (int i=0; i<_NUM_CORE_HEAP; i++) { 9830e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stat_fields[i].pss_field = 9840e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->GetFieldID(clazz, stat_field_names[i].pss_name, "I"); 9853c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum stat_fields[i].pssSwappable_field = 9863c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum env->GetFieldID(clazz, stat_field_names[i].pssSwappable_name, "I"); 9870e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stat_fields[i].privateDirty_field = 9880e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->GetFieldID(clazz, stat_field_names[i].privateDirty_name, "I"); 9890e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn stat_fields[i].sharedDirty_field = 9900e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn env->GetFieldID(clazz, stat_field_names[i].sharedDirty_name, "I"); 9913c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum stat_fields[i].privateClean_field = 9923c61506b7147e13b9d39fc07fb189504fcab4541Anwar Ghuloum env->GetFieldID(clazz, stat_field_names[i].privateClean_name, "I"); 9933a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum stat_fields[i].sharedClean_field = 9943a8ce1bec819c9b104880493a6862fd2a9546132Anwar Ghuloum env->GetFieldID(clazz, stat_field_names[i].sharedClean_name, "I"); 9958883ced18ac25199330843964634fdf70647a127Dianne Hackborn stat_fields[i].swappedOut_field = 9968883ced18ac25199330843964634fdf70647a127Dianne Hackborn env->GetFieldID(clazz, stat_field_names[i].swappedOut_name, "I"); 9970e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn } 9980e3328fbdd3845b0e2bec364e951498eaee6b079Dianne Hackborn 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return jniRegisterNativeMethods(env, "android/os/Debug", gMethods, NELEM(gMethods)); 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 100206a6b558bd03d8f0fed8f94f1dcfc03c5a51bd1cAndy McFadden}; // namespace android 1003