blob: 2ca4500991fac1e2eb6adb51bd332c222764e244 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/* //device/libs/android_runtime/android_ddm_DdmHandleNativeHeap.cpp
2**
3** Copyright 2006, The Android Open Source Project
4**
Elliott Hughesa480daf2013-03-26 13:18:52 -07005** 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08008**
Elliott Hughesa480daf2013-03-26 13:18:52 -07009** http://www.apache.org/licenses/LICENSE-2.0
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080010**
Elliott Hughesa480daf2013-03-26 13:18:52 -070011** 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080015** limitations under the License.
16*/
17
18#undef LOG_TAG
19#define LOG_TAG "DdmHandleNativeHeap"
20
Steven Moreland2279b252017-07-19 09:50:45 -070021#include <nativehelper/JNIHelp.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080022#include <jni.h>
Andreas Gampeed6b9df2014-11-20 22:02:20 -080023#include "core_jni_helpers.h"
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024
Christopher Ferris98180a32019-04-16 11:34:58 -070025#include <android-base/logging.h>
Christopher Ferris8269f3a32019-09-11 19:08:52 -070026#include <bionic/malloc.h>
Christopher Ferris98180a32019-04-16 11:34:58 -070027
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080028#include <utils/Log.h>
Elliott Hughesa480daf2013-03-26 13:18:52 -070029#include <utils/String8.h>
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030
31#include <fcntl.h>
32#include <errno.h>
33#include <sys/types.h>
34#include <sys/stat.h>
35
Christopher Ferrisbebb2672014-09-02 12:49:32 -070036#define DDMS_HEADER_SIGNATURE 0x812345dd
37#define DDMS_VERSION 2
38
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039struct Header {
Christopher Ferrisbebb2672014-09-02 12:49:32 -070040#if defined(__LP64__)
41 uint32_t signature;
42 uint16_t version;
43 uint16_t pointerSize;
44#endif
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045 size_t mapSize;
46 size_t allocSize;
47 size_t allocInfoSize;
48 size_t totalMemory;
49 size_t backtraceSize;
50};
51
52namespace android {
53
Elliott Hughesa480daf2013-03-26 13:18:52 -070054static void ReadFile(const char* path, String8& s) {
Nick Kralevich4b3a08c2019-01-28 10:39:10 -080055 int fd = open(path, O_RDONLY | O_CLOEXEC);
Elliott Hughesa480daf2013-03-26 13:18:52 -070056 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
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066/*
Elliott Hughesa480daf2013-03-26 13:18:52 -070067 * Retrieve the native heap information and the info from /proc/self/maps,
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080068 * copy them into a byte[] with a "struct Header" that holds data offsets,
69 * and return the array.
70 */
Elliott Hughesa480daf2013-03-26 13:18:52 -070071static jbyteArray DdmHandleNativeHeap_getLeakInfo(JNIEnv* env, jobject) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080072 Header header;
73 memset(&header, 0, sizeof(header));
74
Elliott Hughesa480daf2013-03-26 13:18:52 -070075 String8 maps;
76 ReadFile("/proc/self/maps", maps);
77 header.mapSize = maps.size();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078
Christopher Ferris98180a32019-04-16 11:34:58 -070079 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;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089
Dan Albert46d84442014-11-18 16:07:51 -080090 ALOGD("*** mapSize: %zu allocSize: %zu allocInfoSize: %zu totalMemory: %zu",
Elliott Hughesa480daf2013-03-26 13:18:52 -070091 header.mapSize, header.allocSize, header.allocInfoSize, header.totalMemory);
92
Christopher Ferrisbebb2672014-09-02 12:49:32 -070093#if defined(__LP64__)
94 header.signature = DDMS_HEADER_SIGNATURE;
95 header.version = DDMS_VERSION;
96 header.pointerSize = sizeof(void*);
97#endif
98
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080099 jbyteArray array = env->NewByteArray(sizeof(Header) + header.mapSize + header.allocSize);
Elliott Hughesa480daf2013-03-26 13:18:52 -0700100 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(),
Christopher Ferris98180a32019-04-16 11:34:58 -0700106 header.allocSize, reinterpret_cast<jbyte*>(leak_info.buffer));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800107 }
108
Christopher Ferris98180a32019-04-16 11:34:58 -0700109 android_mallopt(M_FREE_MALLOC_LEAK_INFO, &leak_info, sizeof(leak_info));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110 return array;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800111}
112
Daniel Micay76f6a862015-09-19 17:31:01 -0400113static const JNINativeMethod method_table[] = {
Elliott Hughesa480daf2013-03-26 13:18:52 -0700114 { "getLeakInfo", "()[B", (void*) DdmHandleNativeHeap_getLeakInfo },
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800115};
116
Elliott Hughesa480daf2013-03-26 13:18:52 -0700117int register_android_ddm_DdmHandleNativeHeap(JNIEnv* env) {
Andreas Gampeed6b9df2014-11-20 22:02:20 -0800118 return RegisterMethodsOrDie(env, "android/ddm/DdmHandleNativeHeap", method_table,
119 NELEM(method_table));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800120}
121
122};