18d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen/* 28d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen * Copyright 2017, The Android Open Source Project 38d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen * 48d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen * Licensed under the Apache License, Version 2.0 (the "License"); 58d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen * you may not use this file except in compliance with the License. 68d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen * You may obtain a copy of the License at 78d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen * 88d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen * http://www.apache.org/licenses/LICENSE-2.0 98d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen * 108d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen * Unless required by applicable law or agreed to in writing, software 118d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen * distributed under the License is distributed on an "AS IS" BASIS, 128d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen * See the License for the specific language governing permissions and 148d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen * limitations under the License. 158d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen */ 168d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen 17484524a246ffe453f8cd89b698a279c23b0bde1fTej Singh#define DEBUG false // STOPSHIP if true 188d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen#include "Log.h" 198d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen 208d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen#include <sstream> 218d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen#include "MemoryLeakTrackUtil.h" 228d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen 238d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen/* 248d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen * The code here originally resided in MediaPlayerService.cpp 258d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen */ 268d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen 278d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen// Figure out the abi based on defined macros. 288d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen#if defined(__arm__) 298d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen#define ABI_STRING "arm" 308d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen#elif defined(__aarch64__) 318d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen#define ABI_STRING "arm64" 328d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen#elif defined(__mips__) && !defined(__LP64__) 338d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen#define ABI_STRING "mips" 348d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen#elif defined(__mips__) && defined(__LP64__) 358d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen#define ABI_STRING "mips64" 368d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen#elif defined(__i386__) 378d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen#define ABI_STRING "x86" 388d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen#elif defined(__x86_64__) 398d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen#define ABI_STRING "x86_64" 408d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen#else 418d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen#error "Unsupported ABI" 428d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen#endif 438d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen 448d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chenextern std::string backtrace_string(const uintptr_t* frames, size_t frame_count); 458d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen 468d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chennamespace android { 478d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chennamespace os { 488d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chennamespace statsd { 498d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen 508d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chenextern "C" void get_malloc_leak_info(uint8_t** info, size_t* overallSize, size_t* infoSize, 518d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen size_t* totalMemory, size_t* backtraceSize); 528d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen 538d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chenextern "C" void free_malloc_leak_info(uint8_t* info); 548d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen 558d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chenstd::string dumpMemInfo(size_t limit) { 568d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen uint8_t* info; 578d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen size_t overallSize; 588d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen size_t infoSize; 598d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen size_t totalMemory; 608d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen size_t backtraceSize; 618d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen get_malloc_leak_info(&info, &overallSize, &infoSize, &totalMemory, &backtraceSize); 628d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen 638d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen size_t count; 648d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen if (info == nullptr || overallSize == 0 || infoSize == 0 || 658d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen (count = overallSize / infoSize) == 0) { 66484524a246ffe453f8cd89b698a279c23b0bde1fTej Singh VLOG("no malloc info, libc.debug.malloc.program property should be set"); 678d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen return std::string(); 688d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen } 698d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen 708d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen std::ostringstream oss; 718d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen oss << totalMemory << " bytes in " << count << " allocations\n"; 728d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen oss << " ABI: '" ABI_STRING "'" 738d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen << "\n\n"; 748d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen if (count > limit) count = limit; 758d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen 768d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen // The memory is sorted based on total size which is useful for finding 778d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen // worst memory offenders. For diffs, sometimes it is preferable to sort 788d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen // based on the backtrace. 798d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen for (size_t i = 0; i < count; i++) { 808d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen struct AllocEntry { 818d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen size_t size; // bit 31 is set if this is zygote allocated memory 828d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen size_t allocations; 838d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen uintptr_t backtrace[]; 848d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen }; 858d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen 868d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen const AllocEntry* const e = (AllocEntry*)(info + i * infoSize); 878d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen 888d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen oss << (e->size * e->allocations) << " bytes ( " << e->size << " bytes * " << e->allocations 898d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen << " allocations )\n"; 908d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen oss << backtrace_string(e->backtrace, backtraceSize) << "\n"; 918d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen } 928d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen oss << "\n"; 938d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen free_malloc_leak_info(info); 948d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen return oss.str(); 958d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen} 968d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen 978d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen} // namespace statsd 988d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen} // namespace os 998d9989bb376f3937d9c8fef07c9cc65ef78cbcaeYao Chen} // namespace android