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
This commit is contained in:
@@ -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',
|
||||
|
172
src/gallium/auxiliary/util/p_debug_mem.c
Normal file
172
src/gallium/auxiliary/util/p_debug_mem.c
Normal file
@@ -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 <jrfonseca@tungstengraphics.com>
|
||||
*/
|
||||
|
||||
#ifdef WIN32
|
||||
#include <windows.h>
|
||||
#include <winddi.h>
|
||||
#else
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#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);
|
||||
}
|
||||
}
|
@@ -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
|
||||
|
@@ -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))
|
||||
|
||||
|
Reference in New Issue
Block a user