平台
RK3288 + Android 7.1
问题
dumpsys meminfo 执行后无法获取APP内存信息
问题LOG:
rk3288:/ $ dumpsys meminfo Applications Memory Usage (in Kilobytes): Uptime: 2236645 Realtime: 2236645 Total PSS by process: 70,361K: system (pid 380) 18,544K: com.android.settings (pid 631) 8,734K: android.rockchip.update.service (pid 1184) 6,630K: com.android.keychain (pid 1137) 6,393K: com.hsdz.systemcontroler:shellservice (pid 728) 6,341K: com.hsdz.systemcontroler:sysinfo (pid 745) 5,965K: com.cghs.stresstest (pid 1029) 558K: servicemanager (pid 204) 0K: com.android.providers.calendar (pid 1284) 0K: android.process.media (pid 1200) 0K: com.android.printspooler (pid 1051) 0K: com.android.calendar (pid 1240) 0K: com.android.email (pid 1268) 0K: com.android.onetimeinitializer (pid 1330) 0K: com.android.managedprovisioning (pid 1313) 0K: com.android.deskclock (pid 998) 0K: com.android.launcher3 (pid 1100 / activities) 0K: com.android.inputmethod.pinyin (pid 1013) 0K: com.android.smspush (pid 1084) 0K: android.ext.services (pid 978) 0K: com.android.systemui (pid 608) 0K: com.android.phone (pid 603) 0K: /init (pid 1) 0K: ueventd (pid 162) 0K: logd (pid 182) 0K: debuggerd (pid 189) 0K: vold (pid 190) 0K: debuggerd:signaller (pid 191) 0K: healthd (pid 200) 0K: displayd (pid 201) 0K: tee-supplicant (pid 202) 0K: lmkd (pid 203) 0K: surfaceflinger (pid 205) 0K: sh (pid 214) 0K: rild (pid 215) 0K: adbd (pid 217) 0K: zygote (pid 223) 0K: audioserver (pid 224) 0K: cameraserver (pid 225) 0K: drmserver (pid 226) 0K: installd (pid 227) 0K: keystore (pid 228) 0K: media.codec (pid 229) 0K: mediadrmserver (pid 230) 0K: media.extractor (pid 231) 0K: mediaserver (pid 232) 0K: netd (pid 233) 0K: gatekeeperd (pid 234) 0K: perfprofd (pid 241) 0K: logcat (pid 1369) 0K: sh (pid 1388) 0K: transport (pid 1390) 0K: sh (pid 1409) 0K: dumpsys (pid 1441) Total PSS by OOM adjustment: 558K: Native 558K: servicemanager (pid 204) 0K: /init (pid 1) 0K: ueventd (pid 162) 0K: logd (pid 182) 0K: debuggerd (pid 189) 0K: vold (pid 190) 0K: debuggerd:signaller (pid 191) 0K: healthd (pid 200) 0K: displayd (pid 201) 0K: tee-supplicant (pid 202) 0K: lmkd (pid 203) 0K: surfaceflinger (pid 205) 0K: sh (pid 214) 0K: rild (pid 215) 0K: adbd (pid 217) 0K: zygote (pid 223) 0K: audioserver (pid 224) 0K: cameraserver (pid 225) 0K: drmserver (pid 226) 0K: installd (pid 227) 0K: keystore (pid 228) 0K: media.codec (pid 229) 0K: mediadrmserver (pid 230) 0K: media.extractor (pid 231) 0K: mediaserver (pid 232) 0K: netd (pid 233) 0K: gatekeeperd (pid 234) 0K: perfprofd (pid 241) 0K: logcat (pid 1369) 0K: sh (pid 1388) 0K: transport (pid 1390) 0K: sh (pid 1409) 0K: dumpsys (pid 1441) 70,361K: System 70,361K: system (pid 380) 5,965K: Persistent 5,965K: com.cghs.stresstest (pid 1029) 0K: com.android.systemui (pid 608) 0K: com.android.phone (pid 603) 15,075K: A Services 8,734K: android.rockchip.update.service (pid 1184) 6,341K: com.hsdz.systemcontroler:sysinfo (pid 745) 6,393K: B Services 6,393K: com.hsdz.systemcontroler:shellservice (pid 728) 25,174K: Cached 18,544K: com.android.settings (pid 631) 6,630K: com.android.keychain (pid 1137) 0K: com.android.providers.calendar (pid 1284) 0K: android.process.media (pid 1200) 0K: com.android.printspooler (pid 1051) 0K: com.android.calendar (pid 1240) 0K: com.android.email (pid 1268) 0K: com.android.onetimeinitializer (pid 1330) 0K: com.android.managedprovisioning (pid 1313) 0K: com.android.deskclock (pid 998) Total PSS by category: 27,403K: .dex mmap 20,264K: Native 16,707K: .oat mmap 16,285K: Dalvik 11,203K: .apk mmap 10,282K: .art mmap 10,104K: .so mmap 3,947K: Dalvik Other 3,886K: Unknown 1,816K: Other mmap 1,126K: .jar mmap 232K: Stack 106K: .ttf mmap 90K: Ashmem 75K: Other dev 0K: Cursor 0K: Gfx dev 0K: EGL mtrack 0K: GL mtrack 0K: Other mtrack Total RAM: 2,044,596K (status normal) Free RAM: 1,405,270K ( 25,174K cached pss + 112,564K cached kernel + 1,267,532K free) Used RAM: 367,200K ( 98,352K used pss + 268,848K kernel) Lost RAM: 272,122K ZRAM: 4K physical used for 0K in swap ( 520,908K total swap) Tuning: 192 (large 512), oom 184,320K, restore limit 61,440K (high-end-gfx)
问题LOG 2:获取某个应用内存:
rk3288:/ $ dumpsys meminfo com.android.systemui Applications Memory Usage (in Kilobytes): Uptime: 2218086 Realtime: 2218087 ** MEMINFO in pid 608 [com.android.systemui] ** Pss Private Private Swap Heap Heap Heap Total Dirty Clean Dirty Size Alloc Free ------ ------ ------ ------ ------ ------ ------ Native Heap 0 0 0 0 13312 10980 2331 Dalvik Heap 0 0 0 0 11424 6855 4569 Unknown 0 0 0 0 TOTAL 0 0 0 0 24736 17835 6900 App Summary Pss(KB) ------ Java Heap: 0 Native Heap: 0 Code: 0 Stack: 0 Graphics: 0 Private Other: 0 System: 0 TOTAL: 0 TOTAL SWAP (KB): 0 Objects Views: 538 ViewRootImpl: 4 AppContexts: 9 Activities: 0 Assets: 3 AssetManagers: 5 Local Binders: 118 Proxy Binders: 49 Parcel memory: 9 Parcel count: 39 Death Recipients: 1 OpenSSL Sockets: 0 WebViews: 0 SQL MEMORY_USED: 0 PAGECACHE_OVERFLOW: 0 MALLOC_SIZE: 0
正常LOG:
rk3288:/ $ dumpsys meminfo com.android.settings Applications Memory Usage (in Kilobytes): Uptime: 2281967 Realtime: 2281967 ** MEMINFO in pid 631 [com.android.settings] ** Pss Private Private SwapPss Heap Heap Heap Total Dirty Clean Dirty Size Alloc Free ------ ------ ------ ------ ------ ------ ------ Native Heap 3479 3396 0 0 8192 4758 3433 Dalvik Heap 1629 1580 0 0 3572 2679 893 Dalvik Other 236 236 0 0 Stack 36 36 0 0 Ashmem 4 4 0 0 Other dev 10 0 8 0 .so mmap 2128 124 0 0 .apk mmap 3274 0 96 0 .ttf mmap 106 0 40 0 .dex mmap 2952 4 2948 0 .oat mmap 2204 0 68 0 .art mmap 1400 964 0 0 Other mmap 527 4 0 0 Unknown 559 544 0 0 TOTAL 18544 6892 3160 0 11764 7437 4326 App Summary Pss(KB) ------ Java Heap: 2544 Native Heap: 3396 Code: 3280 Stack: 36 Graphics: 0 Private Other: 796 System: 8492 TOTAL: 18544 TOTAL SWAP PSS: 0 Objects Views: 1 ViewRootImpl: 0 AppContexts: 2 Activities: 0 Assets: 2 AssetManagers: 2 Local Binders: 10 Proxy Binders: 13 Parcel memory: 3 Parcel count: 12 Death Recipients: 0 OpenSSL Sockets: 0 WebViews: 0 SQL MEMORY_USED: 0 PAGECACHE_OVERFLOW: 0 MALLOC_SIZE: 0
分析
frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
final void dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) { boolean dumpDetails = false; boolean dumpFullDetails = false; boolean dumpDalvik = false; boolean dumpSummaryOnly = false; boolean dumpUnreachable = false; boolean oomOnly = false; boolean isCompact = false; boolean localOnly = false; boolean packages = false; boolean isCheckinRequest = false; boolean dumpSwapPss = false; //... if (mi == null) { mi = new Debug.MemoryInfo(); } if (dumpDetails || (!brief && !oomOnly)) { Debug.getMemoryInfo(pid, mi); hasSwapPss = mi.hasSwappedOutPss; } else { mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null); mi.dalvikPrivateDirty = (int)tmpLong[0]; } //... }
frameworks/base/core/java/android/os/Debug.java
/** * Retrieves information about this processes memory usages. This information is broken down by * how much is in use by dalvik, the native heap, and everything else. * * <p><b>Note:</b> this method directly retrieves memory information for the give process * from low-level data available to it. It may not be able to retrieve information about * some protected allocations, such as graphics. If you want to be sure you can see * all information about allocations by the process, use instead * {@link android.app.ActivityManager#getProcessMemoryInfo(int[])}.</p> */ public static native void getMemoryInfo(MemoryInfo memoryInfo);
frameworks/base/core/jni/android_os_Debug.cpp
static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz, jint pid, jobject object) { bool foundSwapPss; stats_t stats[_NUM_HEAP]; memset(&stats, 0, sizeof(stats)); load_maps(pid, stats, &foundSwapPss); struct graphics_memory_pss graphics_mem; if (read_memtrack_memory(pid, &graphics_mem) == 0) { stats[HEAP_GRAPHICS].pss = graphics_mem.graphics; stats[HEAP_GRAPHICS].privateDirty = graphics_mem.graphics; stats[HEAP_GL].pss = graphics_mem.gl; stats[HEAP_GL].privateDirty = graphics_mem.gl; stats[HEAP_OTHER_MEMTRACK].pss = graphics_mem.other; stats[HEAP_OTHER_MEMTRACK].privateDirty = graphics_mem.other; } for (int i=_NUM_CORE_HEAP; i<_NUM_EXCLUSIVE_HEAP; i++) { stats[HEAP_UNKNOWN].pss += stats[i].pss; stats[HEAP_UNKNOWN].swappablePss += stats[i].swappablePss; stats[HEAP_UNKNOWN].privateDirty += stats[i].privateDirty; stats[HEAP_UNKNOWN].sharedDirty += stats[i].sharedDirty; stats[HEAP_UNKNOWN].privateClean += stats[i].privateClean; stats[HEAP_UNKNOWN].sharedClean += stats[i].sharedClean; stats[HEAP_UNKNOWN].swappedOut += stats[i].swappedOut; stats[HEAP_UNKNOWN].swappedOutPss += stats[i].swappedOutPss; } for (int i=0; i<_NUM_CORE_HEAP; i++) { env->SetIntField(object, stat_fields[i].pss_field, stats[i].pss); env->SetIntField(object, stat_fields[i].pssSwappable_field, stats[i].swappablePss); env->SetIntField(object, stat_fields[i].privateDirty_field, stats[i].privateDirty); env->SetIntField(object, stat_fields[i].sharedDirty_field, stats[i].sharedDirty); env->SetIntField(object, stat_fields[i].privateClean_field, stats[i].privateClean); env->SetIntField(object, stat_fields[i].sharedClean_field, stats[i].sharedClean); env->SetIntField(object, stat_fields[i].swappedOut_field, stats[i].swappedOut); env->SetIntField(object, stat_fields[i].swappedOutPss_field, stats[i].swappedOutPss); } env->SetBooleanField(object, hasSwappedOutPss_field, foundSwapPss); jintArray otherIntArray = (jintArray)env->GetObjectField(object, otherStats_field); jint* otherArray = (jint*)env->GetPrimitiveArrayCritical(otherIntArray, 0); if (otherArray == NULL) { return; } int j=0; for (int i=_NUM_CORE_HEAP; i<_NUM_HEAP; i++) { otherArray[j++] = stats[i].pss; otherArray[j++] = stats[i].swappablePss; otherArray[j++] = stats[i].privateDirty; otherArray[j++] = stats[i].sharedDirty; otherArray[j++] = stats[i].privateClean; otherArray[j++] = stats[i].sharedClean; otherArray[j++] = stats[i].swappedOut; otherArray[j++] = stats[i].swappedOutPss; } env->ReleasePrimitiveArrayCritical(otherIntArray, otherArray, 0); }
static void load_maps(int pid, stats_t* stats, bool* foundSwapPss) { char tmp[128]; FILE *fp; sprintf(tmp, "/proc/%d/smaps", pid); fp = fopen(tmp, "r"); if (fp == 0) { //问题点在这里, 读取smaps文件时出现访问权限问题. //load_maps open smaps failed:Permission denied ALOGE("load_maps open smaps failed:%s", strerror(errno)); return; } read_mapinfo(fp, stats, foundSwapPss); fclose(fp); }
看下权限,
#SELINUX rk3288:/proc/1 # ps -Z 397 LABEL USER PID PPID VSIZE RSS WCHAN PC NAME u:r:system_server:s0 system 397 221 1621612 165364 SyS_epoll_ adc7f7a4 S system_server rk3288:/ $ ls -lZ proc/1176/smaps -r--r--r-- 1 u0_a19 u0_a19 u:r:platform_app:s0:c512,c768 0 2013-01-18 23:25 proc/1176/smaps ##LINUX rk3288:/ $ ls -l proc/1176/smaps -r--r--r-- 1 u0_a19 u0_a19 0 2013-01-18 23:25 proc/1176/smaps
初步判断权限的问题点:
1.SELINUX
2.基本文件权限
一般情况下, SELINUX的LOG会出现:
type=1400 audit(1358525621.570:41): avc: denied { read open } for pid=1449 comm="rmlogger" path="/data/media/0" dev="mmcblk1p14" ino=1137 scontext=u:r:rmlogger:s0 tcontext=u:object_r:media_rw_data_file:s0 tclass=dir permissive=1
然而在多次测试后, 并没有出现类似问题的LOG
之后, 开始折腾这两个文件 :
kernel/fs/namei.c kernel/fs/open.c
加了一堆关于 -EACCES的LOG, 始终定位不到问题…
最后, 终于在GOOGLE上找到:
framework
kernel
补丁打上, 解决
引用
dumpsys meminfo分析
Linux open系统调用流程浅析
open.c源代码阅读
Androiod 安全上下文的临时更改,命令