1eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr/* 2eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr * Copyright 2017 The Android Open Source Project 3eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr * 4eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr * Licensed under the Apache License, Version 2.0 (the "License"); 5eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr * you may not use this file except in compliance with the License. 6eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr * You may obtain a copy of the License at 7eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr * 8eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr * http://www.apache.org/licenses/LICENSE-2.0 9eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr * 10eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr * Unless required by applicable law or agreed to in writing, software 11eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr * distributed under the License is distributed on an "AS IS" BASIS, 12eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr * See the License for the specific language governing permissions and 14eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr * limitations under the License. 15eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr */ 16eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr 17eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr#include <stdio.h> 18eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr#include <stdlib.h> 19eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr#include <string.h> 20eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr 21eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr#include <map> 22eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr 23eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr#include <base/debug/stack_trace.h> 24eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr 25eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr#include <libatap/libatap.h> 26eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr 27eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohrvoid* atap_memcpy(void* dest, const void* src, size_t n) { 28eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr return memcpy(dest, src, n); 29eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr} 30eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr 31eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohrvoid* atap_memset(void* dest, const int c, size_t n) { 32eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr return memset(dest, c, n); 33eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr} 34eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr 35eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohrvoid atap_abort(void) { 36eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr abort(); 37eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr} 38eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr 39eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohrvoid atap_print(const char* message) { 40eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr fprintf(stderr, "%s", message); 41eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr} 42eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr 43eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohrvoid atap_printv(const char* message, ...) { 44eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr va_list ap; 45eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr const char* m; 46eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr 47eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr va_start(ap, message); 48eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr for (m = message; m != NULL; m = va_arg(ap, const char*)) { 49eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr fprintf(stderr, "%s", m); 50eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr } 51eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr va_end(ap); 52eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr} 53eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr 54eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohrsize_t atap_strlen(const char* str) { 55eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr return strlen(str); 56eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr} 57eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr 58eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohrtypedef struct { 59eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr size_t size; 60eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr base::debug::StackTrace stack_trace; 61eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr} AtapAllocatedBlock; 62eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr 63eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohrstatic std::map<void*, AtapAllocatedBlock> allocated_blocks; 64eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr 65eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohrvoid* atap_malloc(size_t size) { 66eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr void* ptr = malloc(size); 67eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr atap_assert(ptr != nullptr); 68eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr AtapAllocatedBlock block; 69eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr block.size = size; 70eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr allocated_blocks[ptr] = block; 71eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr return ptr; 72eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr} 73eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr 74eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohrvoid atap_free(void* ptr) { 75eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr auto block_it = allocated_blocks.find(ptr); 76eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr if (block_it == allocated_blocks.end()) { 77eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr atap_fatal("Tried to free pointer to non-allocated block.\n"); 78eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr return; 79eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr } 80eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr allocated_blocks.erase(block_it); 81eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr free(ptr); 82eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr} 83eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr 84eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohrnamespace atap { 85eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr 86eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohrvoid testing_memory_reset() { 87eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr allocated_blocks.clear(); 88eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr} 89eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr 90eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohrbool testing_memory_all_freed() { 91eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr if (allocated_blocks.size() == 0) { 92eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr return true; 93eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr } 94eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr 95eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr size_t sum = 0; 96eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr for (const auto& block_it : allocated_blocks) { 97eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr sum += block_it.second.size; 98eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr } 99eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr fprintf(stderr, 100eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr "%zd bytes still allocated in %zd blocks:\n", 101eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr sum, 102eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr allocated_blocks.size()); 103eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr size_t n = 0; 104eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr for (const auto& block_it : allocated_blocks) { 105eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr fprintf(stderr, 106eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr "--\nAllocation %zd/%zd of %zd bytes:\n", 107eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr 1 + n++, 108eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr allocated_blocks.size(), 109eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr block_it.second.size); 110eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr block_it.second.stack_trace.Print(); 111eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr } 112eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr return false; 113eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr} 114eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr 115eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr// Also check leaks at process exit. 116eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr__attribute__((destructor)) static void ensure_all_memory_freed_at_exit() { 117eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr if (!testing_memory_all_freed()) { 118eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr atap_fatal("libatap memory leaks at process exit.\n"); 119eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr } 120eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr} 121eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr 122eb3a3e3eafd643fb61456dfda4eca3c61d50ff14Jocelyn Bohr} // namespace atap 123