• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* //device/libs/android_runtime/android_ddm_DdmHandleNativeHeap.cpp
2 **
3 ** Copyright 2006, The Android Open Source Project
4 **
5 ** Licensed under the Apache License, Version 2.0 (the "License");
6 ** you may not use this file except in compliance with the License.
7 ** You may obtain a copy of the License at
8 **
9 **     http://www.apache.org/licenses/LICENSE-2.0
10 **
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 */
17 
18 #undef LOG_TAG
19 #define LOG_TAG "DdmHandleNativeHeap"
20 
21 #include <nativehelper/JNIHelp.h>
22 #include <jni.h>
23 #include "core_jni_helpers.h"
24 
25 #include <android-base/logging.h>
26 #include <bionic_malloc.h>
27 
28 #include <utils/Log.h>
29 #include <utils/String8.h>
30 
31 #include <fcntl.h>
32 #include <errno.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 
36 #define DDMS_HEADER_SIGNATURE 0x812345dd
37 #define DDMS_VERSION 2
38 
39 struct Header {
40 #if defined(__LP64__)
41     uint32_t signature;
42     uint16_t version;
43     uint16_t pointerSize;
44 #endif
45     size_t mapSize;
46     size_t allocSize;
47     size_t allocInfoSize;
48     size_t totalMemory;
49     size_t backtraceSize;
50 };
51 
52 namespace android {
53 
ReadFile(const char * path,String8 & s)54 static void ReadFile(const char* path, String8& s) {
55     int fd = open(path, O_RDONLY | O_CLOEXEC);
56     if (fd != -1) {
57         char bytes[1024];
58         ssize_t byteCount;
59         while ((byteCount = TEMP_FAILURE_RETRY(read(fd, bytes, sizeof(bytes)))) > 0) {
60             s.append(bytes, byteCount);
61         }
62         close(fd);
63     }
64 }
65 
66 /*
67  * Retrieve the native heap information and the info from /proc/self/maps,
68  * copy them into a byte[] with a "struct Header" that holds data offsets,
69  * and return the array.
70  */
DdmHandleNativeHeap_getLeakInfo(JNIEnv * env,jobject)71 static jbyteArray DdmHandleNativeHeap_getLeakInfo(JNIEnv* env, jobject) {
72     Header header;
73     memset(&header, 0, sizeof(header));
74 
75     String8 maps;
76     ReadFile("/proc/self/maps", maps);
77     header.mapSize = maps.size();
78 
79     android_mallopt_leak_info_t leak_info;
80     if (!android_mallopt(M_GET_MALLOC_LEAK_INFO, &leak_info, sizeof(leak_info))) {
81       PLOG(ERROR) << "*** Failed to get malloc leak info";
82       return nullptr;
83     }
84 
85     header.allocSize = leak_info.overall_size;
86     header.allocInfoSize = leak_info.info_size;
87     header.totalMemory = leak_info.total_memory;
88     header.backtraceSize = leak_info.backtrace_size;
89 
90     ALOGD("*** mapSize: %zu allocSize: %zu allocInfoSize: %zu totalMemory: %zu",
91           header.mapSize, header.allocSize, header.allocInfoSize, header.totalMemory);
92 
93 #if defined(__LP64__)
94     header.signature = DDMS_HEADER_SIGNATURE;
95     header.version = DDMS_VERSION;
96     header.pointerSize = sizeof(void*);
97 #endif
98 
99     jbyteArray array = env->NewByteArray(sizeof(Header) + header.mapSize + header.allocSize);
100     if (array != NULL) {
101         env->SetByteArrayRegion(array, 0,
102                                 sizeof(header), reinterpret_cast<jbyte*>(&header));
103         env->SetByteArrayRegion(array, sizeof(header),
104                                 maps.size(), reinterpret_cast<const jbyte*>(maps.string()));
105         env->SetByteArrayRegion(array, sizeof(header) + maps.size(),
106                                 header.allocSize, reinterpret_cast<jbyte*>(leak_info.buffer));
107     }
108 
109     android_mallopt(M_FREE_MALLOC_LEAK_INFO, &leak_info, sizeof(leak_info));
110     return array;
111 }
112 
113 static const JNINativeMethod method_table[] = {
114     { "getLeakInfo", "()[B", (void*) DdmHandleNativeHeap_getLeakInfo },
115 };
116 
register_android_ddm_DdmHandleNativeHeap(JNIEnv * env)117 int register_android_ddm_DdmHandleNativeHeap(JNIEnv* env) {
118     return RegisterMethodsOrDie(env, "android/ddm/DdmHandleNativeHeap", method_table,
119                                 NELEM(method_table));
120 }
121 
122 };
123