From 732422f6708199d6655185b1a5daec86efe2f1b7 Mon Sep 17 00:00:00 2001 From: José Fonseca Date: Sun, 23 Mar 2008 18:38:10 +0000 Subject: gallium: Memory debugging utilities. There are no known tools for windows kernel memory debugging, so this is a simple set of malloc etc wrappers. Enabled by default on win32 debug builds --- src/gallium/auxiliary/util/SConscript | 1 + src/gallium/auxiliary/util/p_debug_mem.c | 172 +++++++++++++++++++++++++++++++ src/gallium/include/pipe/p_debug.h | 23 +++++ src/gallium/include/pipe/p_util.h | 21 +++- 4 files changed, 215 insertions(+), 2 deletions(-) create mode 100644 src/gallium/auxiliary/util/p_debug_mem.c (limited to 'src/gallium') diff --git a/src/gallium/auxiliary/util/SConscript b/src/gallium/auxiliary/util/SConscript index b44f2d5e39..9b3929eb2d 100644 --- a/src/gallium/auxiliary/util/SConscript +++ b/src/gallium/auxiliary/util/SConscript @@ -4,6 +4,7 @@ util = env.ConvenienceLibrary( target = 'util', source = [ 'p_debug.c', + 'p_debug_mem.c', 'p_tile.c', 'p_util.c', 'u_blit.c', diff --git a/src/gallium/auxiliary/util/p_debug_mem.c b/src/gallium/auxiliary/util/p_debug_mem.c new file mode 100644 index 0000000000..56599dafa6 --- /dev/null +++ b/src/gallium/auxiliary/util/p_debug_mem.c @@ -0,0 +1,172 @@ +/************************************************************************** + * + * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sub license, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. + * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, + * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE + * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + **************************************************************************/ + +/** + * @file + * Memory debugging. + * + * @author José Fonseca + */ + +#ifdef WIN32 +#include +#include +#else +#include +#include +#endif + +#include "pipe/p_debug.h" +#include "util/u_double_list.h" + + +#define DEBUG_MEMORY_MAGIC 0x6e34090aU + + +#if defined(WIN32) && !defined(WINCE) +#define real_malloc(_size) EngAllocMem(0, _size, 'D3AG') +#define real_free(_ptr) EngFreeMem(_ptr) +#else +#define real_malloc(_size) malloc(_size) +#define real_free(_ptr) free(_ptr) +#endif + + +struct debug_memory_header +{ + struct list_head head; + + unsigned long no; + const char *file; + unsigned line; + const char *function; + size_t size; + unsigned magic; +}; + +static struct list_head list = { &list, &list }; + +static unsigned long start_no = 0; +static unsigned long end_no = 0; + + +void * +debug_malloc(const char *file, unsigned line, const char *function, + size_t size) +{ + struct debug_memory_header *hdr; + + hdr = real_malloc(sizeof(*hdr) + size); + if(!hdr) + return NULL; + + hdr->no = end_no++; + hdr->file = file; + hdr->line = line; + hdr->function = function; + hdr->size = size; + hdr->magic = DEBUG_MEMORY_MAGIC; + + LIST_ADDTAIL(&hdr->head, &list); + + return (void *)((char *)hdr + sizeof(*hdr)); +} + +void +debug_free(const char *file, unsigned line, const char *function, + void *ptr) +{ + struct debug_memory_header *hdr; + + if(!ptr) + return; + + hdr = (struct debug_memory_header *)((char *)ptr - sizeof(*hdr)); + if(hdr->magic != DEBUG_MEMORY_MAGIC) { + debug_printf("%s:%u:%s: freeing bad or corrupted memory %p\n", + file, line, function, + ptr); + debug_assert(0); + return; + } + + LIST_DEL(&hdr->head); + hdr->magic = 0; + + real_free(hdr); +} + +void * +debug_calloc(const char *file, unsigned line, const char *function, + size_t count, size_t size ) +{ + void *ptr = debug_malloc( file, line, function, count * size ); + if( ptr ) + memset( ptr, 0, count * size ); + return ptr; +} + +void * +debug_realloc(const char *file, unsigned line, const char *function, + void *old_ptr, size_t old_size, size_t new_size ) +{ + void *new_ptr = NULL; + + if (new_size != 0) { + new_ptr = debug_malloc( file, line, function, new_size ); + + if( new_ptr && old_ptr ) + memcpy( new_ptr, old_ptr, old_size ); + } + + debug_free( file, line, function, old_ptr ); + return new_ptr; +} + +void +debug_memory_reset(void) +{ + start_no = end_no; +} + +void +debug_memory_report(void) +{ + struct list_head *entry; + + entry = list.prev; + for (; entry != &list; entry = entry->prev) { + struct debug_memory_header *hdr; + void *ptr; + hdr = LIST_ENTRY(struct debug_memory_header, entry, head); + ptr = (void *)((char *)hdr + sizeof(*hdr)); + if(hdr->no >= start_no) + debug_printf("%s:%u:%s: %u byte st %p not freed\n", + hdr->file, hdr->line, hdr->function, + hdr->size, ptr); + } +} diff --git a/src/gallium/include/pipe/p_debug.h b/src/gallium/include/pipe/p_debug.h index 14f8056924..c549513b6f 100644 --- a/src/gallium/include/pipe/p_debug.h +++ b/src/gallium/include/pipe/p_debug.h @@ -225,6 +225,29 @@ debug_dump_flags(const struct debug_named_value *names, unsigned long value); +void * +debug_malloc(const char *file, unsigned line, const char *function, + size_t size); + +void +debug_free(const char *file, unsigned line, const char *function, + void *ptr); + +void * +debug_calloc(const char *file, unsigned line, const char *function, + size_t count, size_t size ); + +void * +debug_realloc(const char *file, unsigned line, const char *function, + void *old_ptr, size_t old_size, size_t new_size ); + +void +debug_memory_reset(void); + +void +debug_memory_report(void); + + #ifdef __cplusplus } #endif diff --git a/src/gallium/include/pipe/p_util.h b/src/gallium/include/pipe/p_util.h index c2e0f8c6a5..d3b2fa2950 100644 --- a/src/gallium/include/pipe/p_util.h +++ b/src/gallium/include/pipe/p_util.h @@ -39,6 +39,22 @@ extern "C" { #endif +#if defined(WIN32) && defined(DEBUG) /* memory debugging */ + +#include "p_debug.h" + +#define MALLOC( _size ) \ + debug_malloc( __FILE__, __LINE__, __FUNCTION__, _size ) +#define CALLOC( _count, _size ) \ + debug_calloc(__FILE__, __LINE__, __FUNCTION__, _count, _size ) +#define FREE( _ptr ) \ + debug_free( __FILE__, __LINE__, __FUNCTION__, _ptr ) +#define REALLOC( _ptr, _old_size, _size ) \ + debug_realloc( __FILE__, __LINE__, __FUNCTION__, _ptr, _old_size, _size ) +#define GETENV( X ) NULL + +#else + #ifdef WIN32 void * __stdcall @@ -104,7 +120,7 @@ REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) #define GETENV( X ) NULL -#else /* WIN32 */ +#else /* !WIN32 */ #define MALLOC( SIZE ) malloc( SIZE ) @@ -116,7 +132,8 @@ REALLOC( void *old_ptr, unsigned old_size, unsigned new_size ) #define GETENV( X ) getenv( X ) -#endif /* WIN32 */ +#endif /* !WIN32 */ +#endif /* !DEBUG */ #define MALLOC_STRUCT(T) (struct T *) MALLOC(sizeof(struct T)) -- cgit v1.2.3