1f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/************************************************************************** 2f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 3f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. 4f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * All Rights Reserved. 5f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 6f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Permission is hereby granted, free of charge, to any person obtaining a 7f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * copy of this software and associated documentation files (the 8f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * "Software"), to deal in the Software without restriction, including 9f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * without limitation the rights to use, copy, modify, merge, publish, 10f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * distribute, sub license, and/or sell copies of the Software, and to 11f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * permit persons to whom the Software is furnished to do so, subject to 12f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * the following conditions: 13f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 14f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * The above copyright notice and this permission notice (including the 15f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * next paragraph) shall be included in all copies or substantial portions 16f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * of the Software. 17f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 18f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 19f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 21f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR 22f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 26f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org **************************************************************************/ 27f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 28f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org/** 29f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @file 30f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * Memory debugging. 31f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * 32f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org * @author José Fonseca <jrfonseca@tungstengraphics.com> 33f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org */ 34f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 35f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "pipe/p_config.h" 36f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 37f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DEBUG_MEMORY_IMPLEMENTATION 38f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 39f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "os/os_memory.h" 40f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "os/os_memory_debug.h" 41f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "os/os_thread.h" 42f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 43f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_debug.h" 44f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_debug_stack.h" 45f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#include "util/u_double_list.h" 46f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 47f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 48f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DEBUG_MEMORY_MAGIC 0x6e34090aU 49f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#define DEBUG_MEMORY_STACK 0 /* XXX: disabled until we have symbol lookup */ 50f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 51f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 52f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct debug_memory_header 53f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 54f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct list_head head; 55f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 56f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned long no; 57f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *file; 58f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned line; 59f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org const char *function; 60f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if DEBUG_MEMORY_STACK 61f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct debug_stack_frame backtrace[DEBUG_MEMORY_STACK]; 62f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 63f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org size_t size; 64f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 65f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned magic; 66f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 67f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 68f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstruct debug_memory_footer 69f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 70f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org unsigned magic; 71f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org}; 72f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 73f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 74f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic struct list_head list = { &list, &list }; 75f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 76f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgpipe_static_mutex(list_mutex); 77f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 78f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic unsigned long last_no = 0; 79f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 80f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 81f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE struct debug_memory_header * 82f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgheader_from_data(void *data) 83f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 84f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(data) 85f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (struct debug_memory_header *)((char *)data - sizeof(struct debug_memory_header)); 86f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 87f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 88f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 89f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 90f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE void * 91f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdata_from_header(struct debug_memory_header *hdr) 92f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 93f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(hdr) 94f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (void *)((char *)hdr + sizeof(struct debug_memory_header)); 95f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 96f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 97f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 98f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 99f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgstatic INLINE struct debug_memory_footer * 100f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgfooter_from_header(struct debug_memory_header *hdr) 101f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 102f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(hdr) 103f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return (struct debug_memory_footer *)((char *)hdr + sizeof(struct debug_memory_header) + hdr->size); 104f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else 105f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 106f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 107f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 108f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 109f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid * 110f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdebug_malloc(const char *file, unsigned line, const char *function, 111f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org size_t size) 112f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 113f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct debug_memory_header *hdr; 114f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct debug_memory_footer *ftr; 115f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 116f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hdr = os_malloc(sizeof(*hdr) + size + sizeof(*ftr)); 117f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!hdr) { 118f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("%s:%u:%s: out of memory when trying to allocate %lu bytes\n", 119f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org file, line, function, 120f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (long unsigned)size); 121f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 122f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 123f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 124f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hdr->no = last_no++; 125f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hdr->file = file; 126f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hdr->line = line; 127f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hdr->function = function; 128f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hdr->size = size; 129f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hdr->magic = DEBUG_MEMORY_MAGIC; 130f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 131f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if DEBUG_MEMORY_STACK 132f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_backtrace_capture(hdr->backtrace, 0, DEBUG_MEMORY_STACK); 133f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 134f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 135f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ftr = footer_from_header(hdr); 136f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ftr->magic = DEBUG_MEMORY_MAGIC; 137f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 138f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_mutex_lock(list_mutex); 139f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIST_ADDTAIL(&hdr->head, &list); 140f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_mutex_unlock(list_mutex); 141f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 142f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return data_from_header(hdr); 143f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 144f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 145f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 146f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdebug_free(const char *file, unsigned line, const char *function, 147f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *ptr) 148f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 149f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct debug_memory_header *hdr; 150f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct debug_memory_footer *ftr; 151f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 152f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!ptr) 153f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 154f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 155f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hdr = header_from_data(ptr); 156f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(hdr->magic != DEBUG_MEMORY_MAGIC) { 157f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("%s:%u:%s: freeing bad or corrupted memory %p\n", 158f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org file, line, function, 159f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ptr); 160f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_assert(0); 161f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 162f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 163f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 164f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ftr = footer_from_header(hdr); 165f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(ftr->magic != DEBUG_MEMORY_MAGIC) { 166f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("%s:%u:%s: buffer overflow %p\n", 167f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hdr->file, hdr->line, hdr->function, 168f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ptr); 169f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_assert(0); 170f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 171f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 172f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_mutex_lock(list_mutex); 173f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIST_DEL(&hdr->head); 174f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_mutex_unlock(list_mutex); 175f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hdr->magic = 0; 176f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ftr->magic = 0; 177f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 178f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org os_free(hdr); 179f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 180f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 181f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid * 182f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdebug_calloc(const char *file, unsigned line, const char *function, 183f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org size_t count, size_t size ) 184f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 185f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *ptr = debug_malloc( file, line, function, count * size ); 186f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if( ptr ) 187f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memset( ptr, 0, count * size ); 188f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return ptr; 189f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 190f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 191f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid * 192f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdebug_realloc(const char *file, unsigned line, const char *function, 193f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *old_ptr, size_t old_size, size_t new_size ) 194f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 195f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct debug_memory_header *old_hdr, *new_hdr; 196f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct debug_memory_footer *old_ftr, *new_ftr; 197f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *new_ptr; 198f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 199f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!old_ptr) 200f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return debug_malloc( file, line, function, new_size ); 201f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 202f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!new_size) { 203f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_free( file, line, function, old_ptr ); 204f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 205f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 206f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 207f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org old_hdr = header_from_data(old_ptr); 208f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(old_hdr->magic != DEBUG_MEMORY_MAGIC) { 209f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("%s:%u:%s: reallocating bad or corrupted memory %p\n", 210f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org file, line, function, 211f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org old_ptr); 212f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_assert(0); 213f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 214f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 215f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 216f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org old_ftr = footer_from_header(old_hdr); 217f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(old_ftr->magic != DEBUG_MEMORY_MAGIC) { 218f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("%s:%u:%s: buffer overflow %p\n", 219f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org old_hdr->file, old_hdr->line, old_hdr->function, 220f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org old_ptr); 221f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_assert(0); 222f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 223f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 224f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* alloc new */ 225f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_hdr = os_malloc(sizeof(*new_hdr) + new_size + sizeof(*new_ftr)); 226f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(!new_hdr) { 227f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("%s:%u:%s: out of memory when trying to allocate %lu bytes\n", 228f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org file, line, function, 229f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (long unsigned)new_size); 230f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return NULL; 231f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 232f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_hdr->no = old_hdr->no; 233f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_hdr->file = old_hdr->file; 234f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_hdr->line = old_hdr->line; 235f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_hdr->function = old_hdr->function; 236f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_hdr->size = new_size; 237f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_hdr->magic = DEBUG_MEMORY_MAGIC; 238f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 239f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_ftr = footer_from_header(new_hdr); 240f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_ftr->magic = DEBUG_MEMORY_MAGIC; 241f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 242f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_mutex_lock(list_mutex); 243f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org LIST_REPLACE(&old_hdr->head, &new_hdr->head); 244f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org pipe_mutex_unlock(list_mutex); 245f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 246f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* copy data */ 247f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org new_ptr = data_from_header(new_hdr); 248f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org memcpy( new_ptr, old_ptr, old_size < new_size ? old_size : new_size ); 249f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 250f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org /* free old */ 251f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org old_hdr->magic = 0; 252f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org old_ftr->magic = 0; 253f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org os_free(old_hdr); 254f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 255f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return new_ptr; 256f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 257f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 258f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgunsigned long 259f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdebug_memory_begin(void) 260f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 261f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return last_no; 262f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 263f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 264f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgvoid 265f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.orgdebug_memory_end(unsigned long start_no) 266f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org{ 267f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org size_t total_size = 0; 268f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct list_head *entry; 269f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 270f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(start_no == last_no) 271f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org return; 272f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 273f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org entry = list.prev; 274f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org for (; entry != &list; entry = entry->prev) { 275f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct debug_memory_header *hdr; 276f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org void *ptr; 277f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org struct debug_memory_footer *ftr; 278f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 279f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hdr = LIST_ENTRY(struct debug_memory_header, entry, head); 280f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ptr = data_from_header(hdr); 281f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ftr = footer_from_header(hdr); 282f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 283f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(hdr->magic != DEBUG_MEMORY_MAGIC) { 284f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("%s:%u:%s: bad or corrupted memory %p\n", 285f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hdr->file, hdr->line, hdr->function, 286f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ptr); 287f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_assert(0); 288f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 289f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 290f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if((start_no <= hdr->no && hdr->no < last_no) || 291f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (last_no < start_no && (hdr->no < last_no || start_no <= hdr->no))) { 292f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("%s:%u:%s: %lu bytes at %p not freed\n", 293f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hdr->file, hdr->line, hdr->function, 294f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (unsigned long) hdr->size, ptr); 295f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#if DEBUG_MEMORY_STACK 296f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_backtrace_dump(hdr->backtrace, DEBUG_MEMORY_STACK); 297f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org#endif 298f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org total_size += hdr->size; 299f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 300f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 301f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(ftr->magic != DEBUG_MEMORY_MAGIC) { 302f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("%s:%u:%s: buffer overflow %p\n", 303f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org hdr->file, hdr->line, hdr->function, 304f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org ptr); 305f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_assert(0); 306f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 307f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 308f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org 309f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org if(total_size) { 310f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("Total of %lu KB of system memory apparently leaked\n", 311f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org (unsigned long) (total_size + 1023)/1024); 312f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 313f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org else { 314f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org debug_printf("No memory leaks detected.\n"); 315f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org } 316f2ba7591b1407a7ee9209f842c50696914dc2dedkbr@chromium.org} 317