18635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong/* 28635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong * Copyright 2011, The Android Open Source Project 38635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong * 48635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong * Licensed under the Apache License, Version 2.0 (the "License"); 58635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong * you may not use this file except in compliance with the License. 68635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong * You may obtain a copy of the License at 78635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong * 88635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong * http://www.apache.org/licenses/LICENSE-2.0 98635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong * 108635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong * Unless required by applicable law or agreed to in writing, software 118635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong * distributed under the License is distributed on an "AS IS" BASIS, 128635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong * See the License for the specific language governing permissions and 148635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong * limitations under the License. 158635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong */ 168635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong 178635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong 1807b745e166ee62030960ccea37e117caadf71c32Andy Hung//#define LOG_NDEBUG 0 1907b745e166ee62030960ccea37e117caadf71c32Andy Hung#define LOG_TAG "MemoryLeackTrackUtil" 2007b745e166ee62030960ccea37e117caadf71c32Andy Hung#include <utils/Log.h> 2107b745e166ee62030960ccea37e117caadf71c32Andy Hung 2207b745e166ee62030960ccea37e117caadf71c32Andy Hung#include "media/MemoryLeakTrackUtil.h" 2307b745e166ee62030960ccea37e117caadf71c32Andy Hung#include <sstream> 248635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong 258635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong/* 2607b745e166ee62030960ccea37e117caadf71c32Andy Hung * The code here originally resided in MediaPlayerService.cpp 278635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong */ 288635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong 2907b745e166ee62030960ccea37e117caadf71c32Andy Hung// Figure out the abi based on defined macros. 308635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong#if defined(__arm__) 3107b745e166ee62030960ccea37e117caadf71c32Andy Hung#define ABI_STRING "arm" 3207b745e166ee62030960ccea37e117caadf71c32Andy Hung#elif defined(__aarch64__) 3307b745e166ee62030960ccea37e117caadf71c32Andy Hung#define ABI_STRING "arm64" 3407b745e166ee62030960ccea37e117caadf71c32Andy Hung#elif defined(__mips__) && !defined(__LP64__) 3507b745e166ee62030960ccea37e117caadf71c32Andy Hung#define ABI_STRING "mips" 3607b745e166ee62030960ccea37e117caadf71c32Andy Hung#elif defined(__mips__) && defined(__LP64__) 3707b745e166ee62030960ccea37e117caadf71c32Andy Hung#define ABI_STRING "mips64" 3807b745e166ee62030960ccea37e117caadf71c32Andy Hung#elif defined(__i386__) 3907b745e166ee62030960ccea37e117caadf71c32Andy Hung#define ABI_STRING "x86" 4007b745e166ee62030960ccea37e117caadf71c32Andy Hung#elif defined(__x86_64__) 4107b745e166ee62030960ccea37e117caadf71c32Andy Hung#define ABI_STRING "x86_64" 4207b745e166ee62030960ccea37e117caadf71c32Andy Hung#else 4307b745e166ee62030960ccea37e117caadf71c32Andy Hung#error "Unsupported ABI" 4407b745e166ee62030960ccea37e117caadf71c32Andy Hung#endif 4507b745e166ee62030960ccea37e117caadf71c32Andy Hung 4607b745e166ee62030960ccea37e117caadf71c32Andy Hungextern std::string backtrace_string(const uintptr_t* frames, size_t frame_count); 4707b745e166ee62030960ccea37e117caadf71c32Andy Hung 4807b745e166ee62030960ccea37e117caadf71c32Andy Hungnamespace android { 498635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong 508635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dongextern "C" void get_malloc_leak_info(uint8_t** info, size_t* overallSize, 518635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong size_t* infoSize, size_t* totalMemory, size_t* backtraceSize); 528635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong 538635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dongextern "C" void free_malloc_leak_info(uint8_t* info); 548635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong 5507b745e166ee62030960ccea37e117caadf71c32Andy Hungstd::string dumpMemoryAddresses(size_t limit) 5607b745e166ee62030960ccea37e117caadf71c32Andy Hung{ 5707b745e166ee62030960ccea37e117caadf71c32Andy Hung uint8_t *info; 5807b745e166ee62030960ccea37e117caadf71c32Andy Hung size_t overallSize; 5907b745e166ee62030960ccea37e117caadf71c32Andy Hung size_t infoSize; 6007b745e166ee62030960ccea37e117caadf71c32Andy Hung size_t totalMemory; 6107b745e166ee62030960ccea37e117caadf71c32Andy Hung size_t backtraceSize; 6207b745e166ee62030960ccea37e117caadf71c32Andy Hung get_malloc_leak_info(&info, &overallSize, &infoSize, &totalMemory, &backtraceSize); 638635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong 6407b745e166ee62030960ccea37e117caadf71c32Andy Hung size_t count; 6507b745e166ee62030960ccea37e117caadf71c32Andy Hung if (info == nullptr || overallSize == 0 || infoSize == 0 6607b745e166ee62030960ccea37e117caadf71c32Andy Hung || (count = overallSize / infoSize) == 0) { 6707b745e166ee62030960ccea37e117caadf71c32Andy Hung ALOGD("no malloc info, libc.debug.malloc.program property should be set"); 6807b745e166ee62030960ccea37e117caadf71c32Andy Hung return std::string(); 698635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong } 708635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong 7107b745e166ee62030960ccea37e117caadf71c32Andy Hung std::ostringstream oss; 7207b745e166ee62030960ccea37e117caadf71c32Andy Hung oss << totalMemory << " bytes in " << count << " allocations\n"; 7307b745e166ee62030960ccea37e117caadf71c32Andy Hung oss << " ABI: '" ABI_STRING "'" << "\n\n"; 7407b745e166ee62030960ccea37e117caadf71c32Andy Hung if (count > limit) count = limit; 7507b745e166ee62030960ccea37e117caadf71c32Andy Hung 7607b745e166ee62030960ccea37e117caadf71c32Andy Hung // The memory is sorted based on total size which is useful for finding 7707b745e166ee62030960ccea37e117caadf71c32Andy Hung // worst memory offenders. For diffs, sometimes it is preferable to sort 7807b745e166ee62030960ccea37e117caadf71c32Andy Hung // based on the backtrace. 7907b745e166ee62030960ccea37e117caadf71c32Andy Hung for (size_t i = 0; i < count; i++) { 8007b745e166ee62030960ccea37e117caadf71c32Andy Hung struct AllocEntry { 8107b745e166ee62030960ccea37e117caadf71c32Andy Hung size_t size; // bit 31 is set if this is zygote allocated memory 8207b745e166ee62030960ccea37e117caadf71c32Andy Hung size_t allocations; 8307b745e166ee62030960ccea37e117caadf71c32Andy Hung uintptr_t backtrace[]; 8407b745e166ee62030960ccea37e117caadf71c32Andy Hung }; 8507b745e166ee62030960ccea37e117caadf71c32Andy Hung 8607b745e166ee62030960ccea37e117caadf71c32Andy Hung const AllocEntry * const e = (AllocEntry *)(info + i * infoSize); 8707b745e166ee62030960ccea37e117caadf71c32Andy Hung 8807b745e166ee62030960ccea37e117caadf71c32Andy Hung oss << (e->size * e->allocations) 8907b745e166ee62030960ccea37e117caadf71c32Andy Hung << " bytes ( " << e->size << " bytes * " << e->allocations << " allocations )\n"; 9007b745e166ee62030960ccea37e117caadf71c32Andy Hung oss << backtrace_string(e->backtrace, backtraceSize) << "\n"; 918635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong } 9207b745e166ee62030960ccea37e117caadf71c32Andy Hung oss << "\n"; 9307b745e166ee62030960ccea37e117caadf71c32Andy Hung free_malloc_leak_info(info); 9407b745e166ee62030960ccea37e117caadf71c32Andy Hung return oss.str(); 958635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong} 968635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong 978635b7b095fbf7ffc63d3ce791891a9116ace1f6James Dong} // namespace android 98