Merge "Debug: Use UniqueFile"
This commit is contained in:
@@ -220,6 +220,7 @@ LOCAL_C_INCLUDES += \
|
|||||||
LOCAL_SHARED_LIBRARIES := \
|
LOCAL_SHARED_LIBRARIES := \
|
||||||
libmemtrack \
|
libmemtrack \
|
||||||
libandroidfw \
|
libandroidfw \
|
||||||
|
libbase \
|
||||||
libexpat \
|
libexpat \
|
||||||
libnativehelper \
|
libnativehelper \
|
||||||
liblog \
|
liblog \
|
||||||
|
|||||||
@@ -15,15 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#define LOG_TAG "android.os.Debug"
|
#define LOG_TAG "android.os.Debug"
|
||||||
#include "JNIHelp.h"
|
|
||||||
#include "jni.h"
|
|
||||||
#include <utils/String8.h>
|
|
||||||
#include "utils/misc.h"
|
|
||||||
#include "cutils/debugger.h"
|
|
||||||
#include <memtrack/memtrack.h>
|
|
||||||
#include <memunreachable/memunreachable.h>
|
|
||||||
|
|
||||||
#include <cutils/log.h>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -40,9 +32,26 @@
|
|||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
|
#include "jni.h"
|
||||||
|
|
||||||
|
#include "android-base/stringprintf.h"
|
||||||
|
#include "cutils/debugger.h"
|
||||||
|
#include "cutils/log.h"
|
||||||
|
#include "JNIHelp.h"
|
||||||
|
#include "memtrack/memtrack.h"
|
||||||
|
#include "memunreachable/memunreachable.h"
|
||||||
|
#include "utils/misc.h"
|
||||||
|
#include "utils/String8.h"
|
||||||
|
|
||||||
namespace android
|
namespace android
|
||||||
{
|
{
|
||||||
|
|
||||||
|
using UniqueFile = std::unique_ptr<FILE, decltype(&fclose)>;
|
||||||
|
|
||||||
|
static inline UniqueFile MakeUniqueFile(const char* path, const char* mode) {
|
||||||
|
return UniqueFile(fopen(path, mode), fclose);
|
||||||
|
}
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
HEAP_UNKNOWN,
|
HEAP_UNKNOWN,
|
||||||
HEAP_DALVIK,
|
HEAP_DALVIK,
|
||||||
@@ -427,17 +436,13 @@ static void read_mapinfo(FILE *fp, stats_t* stats, bool* foundSwapPss)
|
|||||||
|
|
||||||
static void load_maps(int pid, stats_t* stats, bool* foundSwapPss)
|
static void load_maps(int pid, stats_t* stats, bool* foundSwapPss)
|
||||||
{
|
{
|
||||||
char tmp[128];
|
|
||||||
FILE *fp;
|
|
||||||
|
|
||||||
*foundSwapPss = false;
|
*foundSwapPss = false;
|
||||||
|
|
||||||
sprintf(tmp, "/proc/%d/smaps", pid);
|
std::string smaps_path = base::StringPrintf("/proc/%d/smaps", pid);
|
||||||
fp = fopen(tmp, "r");
|
UniqueFile fp = MakeUniqueFile(smaps_path.c_str(), "re");
|
||||||
if (fp == 0) return;
|
if (fp == nullptr) return;
|
||||||
|
|
||||||
read_mapinfo(fp, stats, foundSwapPss);
|
read_mapinfo(fp.get(), stats, foundSwapPss);
|
||||||
fclose(fp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz,
|
static void android_os_Debug_getDirtyPagesPid(JNIEnv *env, jobject clazz,
|
||||||
@@ -519,51 +524,48 @@ static jlong android_os_Debug_getPssPid(JNIEnv *env, jobject clazz, jint pid,
|
|||||||
jlong uss = 0;
|
jlong uss = 0;
|
||||||
jlong memtrack = 0;
|
jlong memtrack = 0;
|
||||||
|
|
||||||
char tmp[128];
|
|
||||||
FILE *fp;
|
|
||||||
|
|
||||||
struct graphics_memory_pss graphics_mem;
|
struct graphics_memory_pss graphics_mem;
|
||||||
if (read_memtrack_memory(pid, &graphics_mem) == 0) {
|
if (read_memtrack_memory(pid, &graphics_mem) == 0) {
|
||||||
pss = uss = memtrack = graphics_mem.graphics + graphics_mem.gl + graphics_mem.other;
|
pss = uss = memtrack = graphics_mem.graphics + graphics_mem.gl + graphics_mem.other;
|
||||||
}
|
}
|
||||||
|
|
||||||
sprintf(tmp, "/proc/%d/smaps", pid);
|
{
|
||||||
fp = fopen(tmp, "r");
|
std::string smaps_path = base::StringPrintf("/proc/%d/smaps", pid);
|
||||||
|
UniqueFile fp = MakeUniqueFile(smaps_path.c_str(), "re");
|
||||||
|
|
||||||
if (fp != 0) {
|
if (fp != nullptr) {
|
||||||
while (true) {
|
while (true) {
|
||||||
if (fgets(line, 1024, fp) == NULL) {
|
if (fgets(line, 1024, fp.get()) == NULL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (line[0] == 'P') {
|
if (line[0] == 'P') {
|
||||||
if (strncmp(line, "Pss:", 4) == 0) {
|
if (strncmp(line, "Pss:", 4) == 0) {
|
||||||
char* c = line + 4;
|
char* c = line + 4;
|
||||||
|
while (*c != 0 && (*c < '0' || *c > '9')) {
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
pss += atoi(c);
|
||||||
|
} else if (strncmp(line, "Private_Clean:", 14) == 0
|
||||||
|
|| strncmp(line, "Private_Dirty:", 14) == 0) {
|
||||||
|
char* c = line + 14;
|
||||||
|
while (*c != 0 && (*c < '0' || *c > '9')) {
|
||||||
|
c++;
|
||||||
|
}
|
||||||
|
uss += atoi(c);
|
||||||
|
}
|
||||||
|
} else if (line[0] == 'S' && strncmp(line, "SwapPss:", 8) == 0) {
|
||||||
|
char* c = line + 8;
|
||||||
|
jlong lSwapPss;
|
||||||
while (*c != 0 && (*c < '0' || *c > '9')) {
|
while (*c != 0 && (*c < '0' || *c > '9')) {
|
||||||
c++;
|
c++;
|
||||||
}
|
}
|
||||||
pss += atoi(c);
|
lSwapPss = atoi(c);
|
||||||
} else if (strncmp(line, "Private_Clean:", 14) == 0
|
swapPss += lSwapPss;
|
||||||
|| strncmp(line, "Private_Dirty:", 14) == 0) {
|
pss += lSwapPss; // Also in swap, those pages would be accounted as Pss without SWAP
|
||||||
char* c = line + 14;
|
|
||||||
while (*c != 0 && (*c < '0' || *c > '9')) {
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
uss += atoi(c);
|
|
||||||
}
|
}
|
||||||
} else if (line[0] == 'S' && strncmp(line, "SwapPss:", 8) == 0) {
|
|
||||||
char* c = line + 8;
|
|
||||||
jlong lSwapPss;
|
|
||||||
while (*c != 0 && (*c < '0' || *c > '9')) {
|
|
||||||
c++;
|
|
||||||
}
|
|
||||||
lSwapPss = atoi(c);
|
|
||||||
swapPss += lSwapPss;
|
|
||||||
pss += lSwapPss; // Also in swap, those pages would be accounted as Pss without SWAP
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (outUssSwapPss != NULL) {
|
if (outUssSwapPss != NULL) {
|
||||||
@@ -607,12 +609,14 @@ static long get_allocated_vmalloc_memory() {
|
|||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
long size, vmalloc_allocated_size = 0;
|
long size, vmalloc_allocated_size = 0;
|
||||||
FILE* fp = fopen("/proc/vmallocinfo", "r");
|
|
||||||
if (fp == NULL) {
|
UniqueFile fp = MakeUniqueFile("/proc/vmallocinfo", "re");
|
||||||
|
if (fp == nullptr) {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
if (fgets(line, 1024, fp) == NULL) {
|
if (fgets(line, 1024, fp.get()) == NULL) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
bool valid_line = true;
|
bool valid_line = true;
|
||||||
@@ -628,7 +632,6 @@ static long get_allocated_vmalloc_memory() {
|
|||||||
vmalloc_allocated_size += size;
|
vmalloc_allocated_size += size;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fclose(fp);
|
|
||||||
return vmalloc_allocated_size;
|
return vmalloc_allocated_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -652,27 +655,25 @@ enum {
|
|||||||
static long long get_zram_mem_used()
|
static long long get_zram_mem_used()
|
||||||
{
|
{
|
||||||
#define ZRAM_SYSFS "/sys/block/zram0/"
|
#define ZRAM_SYSFS "/sys/block/zram0/"
|
||||||
FILE *f = fopen(ZRAM_SYSFS "mm_stat", "r");
|
UniqueFile mm_stat_file = MakeUniqueFile(ZRAM_SYSFS "mm_stat", "re");
|
||||||
if (f) {
|
if (mm_stat_file) {
|
||||||
long long mem_used_total = 0;
|
long long mem_used_total = 0;
|
||||||
|
|
||||||
int matched = fscanf(f, "%*d %*d %lld %*d %*d %*d %*d", &mem_used_total);
|
int matched = fscanf(mm_stat_file.get(), "%*d %*d %lld %*d %*d %*d %*d", &mem_used_total);
|
||||||
if (matched != 1)
|
if (matched != 1)
|
||||||
ALOGW("failed to parse " ZRAM_SYSFS "mm_stat");
|
ALOGW("failed to parse " ZRAM_SYSFS "mm_stat");
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
return mem_used_total;
|
return mem_used_total;
|
||||||
}
|
}
|
||||||
|
|
||||||
f = fopen(ZRAM_SYSFS "mem_used_total", "r");
|
UniqueFile mem_used_total_file = MakeUniqueFile(ZRAM_SYSFS "mem_used_total", "re");
|
||||||
if (f) {
|
if (mem_used_total_file) {
|
||||||
long long mem_used_total = 0;
|
long long mem_used_total = 0;
|
||||||
|
|
||||||
int matched = fscanf(f, "%lld", &mem_used_total);
|
int matched = fscanf(mem_used_total_file.get(), "%lld", &mem_used_total);
|
||||||
if (matched != 1)
|
if (matched != 1)
|
||||||
ALOGW("failed to parse " ZRAM_SYSFS "mem_used_total");
|
ALOGW("failed to parse " ZRAM_SYSFS "mem_used_total");
|
||||||
|
|
||||||
fclose(f);
|
|
||||||
return mem_used_total;
|
return mem_used_total;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -785,8 +786,8 @@ static void android_os_Debug_getMemInfo(JNIEnv *env, jobject clazz, jlongArray o
|
|||||||
|
|
||||||
static jint read_binder_stat(const char* stat)
|
static jint read_binder_stat(const char* stat)
|
||||||
{
|
{
|
||||||
FILE* fp = fopen(BINDER_STATS, "r");
|
UniqueFile fp = MakeUniqueFile(BINDER_STATS, "re");
|
||||||
if (fp == NULL) {
|
if (fp == nullptr) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -797,8 +798,7 @@ static jint read_binder_stat(const char* stat)
|
|||||||
|
|
||||||
// loop until we have the block that represents this process
|
// loop until we have the block that represents this process
|
||||||
do {
|
do {
|
||||||
if (fgets(line, 1024, fp) == 0) {
|
if (fgets(line, 1024, fp.get()) == 0) {
|
||||||
fclose(fp);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} while (strncmp(compare, line, len));
|
} while (strncmp(compare, line, len));
|
||||||
@@ -807,8 +807,7 @@ static jint read_binder_stat(const char* stat)
|
|||||||
len = snprintf(compare, 128, " %s: ", stat);
|
len = snprintf(compare, 128, " %s: ", stat);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
if (fgets(line, 1024, fp) == 0) {
|
if (fgets(line, 1024, fp.get()) == 0) {
|
||||||
fclose(fp);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
} while (strncmp(compare, line, len));
|
} while (strncmp(compare, line, len));
|
||||||
@@ -816,7 +815,6 @@ static jint read_binder_stat(const char* stat)
|
|||||||
// we have the line, now increment the line ptr to the value
|
// we have the line, now increment the line ptr to the value
|
||||||
char* ptr = line + len;
|
char* ptr = line + len;
|
||||||
jint result = atoi(ptr);
|
jint result = atoi(ptr);
|
||||||
fclose(fp);
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -962,16 +960,15 @@ static void dumpNativeHeap(FILE* fp)
|
|||||||
|
|
||||||
fprintf(fp, "MAPS\n");
|
fprintf(fp, "MAPS\n");
|
||||||
const char* maps = "/proc/self/maps";
|
const char* maps = "/proc/self/maps";
|
||||||
FILE* in = fopen(maps, "r");
|
UniqueFile in = MakeUniqueFile(maps, "re");
|
||||||
if (in == NULL) {
|
if (in == nullptr) {
|
||||||
fprintf(fp, "Could not open %s\n", maps);
|
fprintf(fp, "Could not open %s\n", maps);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
char buf[BUFSIZ];
|
char buf[BUFSIZ];
|
||||||
while (size_t n = fread(buf, sizeof(char), BUFSIZ, in)) {
|
while (size_t n = fread(buf, sizeof(char), BUFSIZ, in.get())) {
|
||||||
fwrite(buf, sizeof(char), n, fp);
|
fwrite(buf, sizeof(char), n, fp);
|
||||||
}
|
}
|
||||||
fclose(in);
|
|
||||||
|
|
||||||
fprintf(fp, "END\n");
|
fprintf(fp, "END\n");
|
||||||
}
|
}
|
||||||
@@ -1001,8 +998,8 @@ static void android_os_Debug_dumpNativeHeap(JNIEnv* env, jobject clazz,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* fp = fdopen(fd, "w");
|
UniqueFile fp(fdopen(fd, "w"), fclose);
|
||||||
if (fp == NULL) {
|
if (fp == nullptr) {
|
||||||
ALOGW("fdopen(%d) failed: %s\n", fd, strerror(errno));
|
ALOGW("fdopen(%d) failed: %s\n", fd, strerror(errno));
|
||||||
close(fd);
|
close(fd);
|
||||||
jniThrowRuntimeException(env, "fdopen() failed");
|
jniThrowRuntimeException(env, "fdopen() failed");
|
||||||
@@ -1010,10 +1007,8 @@ static void android_os_Debug_dumpNativeHeap(JNIEnv* env, jobject clazz,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ALOGD("Native heap dump starting...\n");
|
ALOGD("Native heap dump starting...\n");
|
||||||
dumpNativeHeap(fp);
|
dumpNativeHeap(fp.get());
|
||||||
ALOGD("Native heap dump complete.\n");
|
ALOGD("Native heap dump complete.\n");
|
||||||
|
|
||||||
fclose(fp);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user