1/* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17#include "malloc_info.h" 18 19#include <errno.h> 20#include "private/bionic_macros.h" 21 22class __LIBC_HIDDEN__ Elem { 23public: 24 // name must be valid throughout lifetime of the object. 25 explicit Elem(FILE* fp, const char* name, 26 const char* attr_fmt = nullptr, ...) { 27 this->fp = fp; 28 this->name = name; 29 30 fprintf(fp, "<%s", name); 31 if (attr_fmt != nullptr) { 32 va_list args; 33 va_start(args, attr_fmt); 34 fputc(' ', fp); 35 vfprintf(fp, attr_fmt, args); 36 va_end(args); 37 } 38 fputc('>', fp); 39 } 40 41 ~Elem() noexcept { 42 fprintf(fp, "</%s>", name); 43 } 44 45 void contents(const char* fmt, ...) { 46 va_list args; 47 va_start(args, fmt); 48 vfprintf(fp, fmt, args); 49 va_end(args); 50 } 51 52private: 53 FILE* fp; 54 const char* name; 55 56 DISALLOW_COPY_AND_ASSIGN(Elem); 57}; 58 59int malloc_info(int options, FILE* fp) { 60 if (options != 0) { 61 errno = EINVAL; 62 return -1; 63 } 64 65 Elem root(fp, "malloc", "version=\"jemalloc-1\""); 66 67 // Dump all of the large allocations in the arenas. 68 for (size_t i = 0; i < __mallinfo_narenas(); i++) { 69 struct mallinfo mi = __mallinfo_arena_info(i); 70 if (mi.hblkhd != 0) { 71 Elem arena_elem(fp, "heap", "nr=\"%d\"", i); 72 { 73 Elem(fp, "allocated-large").contents("%zu", mi.ordblks); 74 Elem(fp, "allocated-huge").contents("%zu", mi.uordblks); 75 Elem(fp, "allocated-bins").contents("%zu", mi.fsmblks); 76 77 size_t total = 0; 78 for (size_t j = 0; j < __mallinfo_nbins(); j++) { 79 struct mallinfo mi = __mallinfo_bin_info(i, j); 80 if (mi.ordblks != 0) { 81 Elem bin_elem(fp, "bin", "nr=\"%d\"", j); 82 Elem(fp, "allocated").contents("%zu", mi.ordblks); 83 Elem(fp, "nmalloc").contents("%zu", mi.uordblks); 84 Elem(fp, "ndalloc").contents("%zu", mi.fordblks); 85 total += mi.ordblks; 86 } 87 } 88 Elem(fp, "bins-total").contents("%zu", total); 89 } 90 } 91 } 92 93 return 0; 94} 95