diff --git a/ChangeLog b/ChangeLog index 808abd34f..091845884 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,10 @@ 2001-10-22 David Turner + * include/freetype/internal/ftmemory.h, src/base/ftdbgmem.c: modified + the debugging memory manager to report the location (source file name + + line number) where leaked memory blocks are allocated in the source + file.. funny, isn't it ?? + * src/base/ftdbgmem.c: new debugging memory manager. You must define the FT_DEBUG_MEMORY macro in "ftoption.h" to enable it. It will record every memory block allocated and report simple errors like memory diff --git a/docs/TODO b/docs/TODO index c7816a043..76b34fe83 100644 --- a/docs/TODO +++ b/docs/TODO @@ -5,6 +5,3 @@ Here is a list of items that need to be addressed in FreeType 2; they are not exactly bugs, but should be considered though: * Add synthesized Unicode charmap processing to the CFF driver. - -* Add the new auto-hinting source code / native Type1/Type2 hinter - to the source code. diff --git a/include/freetype/internal/ftmemory.h b/include/freetype/internal/ftmemory.h index e64865ea7..1a27e0ef1 100644 --- a/include/freetype/internal/ftmemory.h +++ b/include/freetype/internal/ftmemory.h @@ -55,6 +55,16 @@ FT_BEGIN_HEADER /*************************************************************************/ /*************************************************************************/ +#ifdef FT_DEBUG_MEMORY + + FT_BASE( FT_Error ) + FT_Alloc_Debug( FT_Memory memory, + FT_Long size, + void* *P, + const char* file_name, + FT_Long line_no ); +#endif + /*************************************************************************/ /* */ @@ -83,7 +93,6 @@ FT_BEGIN_HEADER FT_Long size, void* *P ); - /*************************************************************************/ /* */ /* */ @@ -159,6 +168,7 @@ FT_BEGIN_HEADER #define MEM_Move( dest, source, count ) memmove( dest, source, count ) + /*************************************************************************/ /* */ /* We now support closures to produce completely reentrant code. This */ @@ -172,12 +182,26 @@ FT_BEGIN_HEADER /* ALLOC_ARRAY() now use an implicit variable, `memory'. It must be */ /* defined at all locations where a memory operation is queried. */ /* */ -#define MEM_Alloc( _pointer_, _size_ ) \ - FT_Alloc( memory, _size_, (void**)&(_pointer_) ) -#define MEM_Alloc_Array( _pointer_, _count_, _type_ ) \ - FT_Alloc( memory, (_count_)*sizeof ( _type_ ), \ - (void**)&(_pointer_) ) +#ifdef FT_DEBUG_MEMORY + +# define MEM_Alloc( _pointer_, _size_ ) \ + FT_Alloc_Debug( memory, _size_, (void**)&(_pointer_), __FILE__, __LINE__ ) + +# define MEM_Alloc_Array( _pointer_, _count_, _type_ ) \ + FT_Alloc_Debug( memory, (_count_)*sizeof ( _type_ ), \ + (void**)&(_pointer_), __FILE__, __LINE__ ) + +#else /* !FT_DEBUG_MEMORY */ + +# define MEM_Alloc( _pointer_, _size_ ) \ + FT_Alloc( memory, _size_, (void**)&(_pointer_) ) + +# define MEM_Alloc_Array( _pointer_, _count_, _type_ ) \ + FT_Alloc( memory, (_count_)*sizeof ( _type_ ), \ + (void**)&(_pointer_) ) + +#endif /* !FT_DEBUG_MEMORY */ #define MEM_Realloc( _pointer_, _current_, _size_ ) \ FT_Realloc( memory, _current_, _size_, (void**)&(_pointer_) ) diff --git a/src/base/ftdbgmem.c b/src/base/ftdbgmem.c index 35b7b2bda..f35aafb30 100644 --- a/src/base/ftdbgmem.c +++ b/src/base/ftdbgmem.c @@ -20,9 +20,13 @@ typedef struct FT_MemNodeRec_ { - FT_Byte* address; - FT_Long size; /* < 0 if the block was freed */ - FT_MemNode link; + FT_Byte* address; + FT_Long size; /* < 0 if the block was freed */ + + const char* file_name; + FT_Long line_no; + + FT_MemNode link; } FT_MemNodeRec; @@ -36,6 +40,9 @@ FT_ULong alloc_total; FT_ULong alloc_current; + const char* file_name; + FT_Long line_no; + } FT_MemTableRec; #define FT_MEM_SIZE_MIN 7 @@ -160,40 +167,6 @@ } - static FT_MemNode - ft_mem_node_new( FT_MemTable table, - FT_Pointer address, - FT_ULong size ) - { - FT_MemNode node; - - node = malloc( sizeof(*node) ); - if ( node == NULL ) - ft_mem_debug_panic( "not enough memory to run memory tests" ); - - node->link = NULL; - node->address = address; - node->size = size; - - return node; - } - - - static void - ft_mem_node_destroy( FT_MemNode node, - FT_MemTable table ) - { - if (node) - { - node->address = NULL; - node->size = 0; - node->link = NULL; - - free( node ); - } - } - - static FT_MemTable ft_mem_table_new( void ) @@ -244,8 +217,10 @@ if ( node->size > 0 ) { - printf( "leaked memory block at address %p, size %ld\n", - node->address, node->size ); + printf( "leaked memory block at address %p, size %8ld (%s:%d)\n", + node->address, node->size, + node->file_name ? node->file_name : "unknown_file", + node->line_no ); leak_count++; leaks += node->size; @@ -337,9 +312,13 @@ if ( node == NULL ) ft_mem_debug_panic( "not enough memory to run memory tests" ); - node->address = address; - node->size = size; - node->link = pnode[0]; + node->address = address; + node->size = size; + + node->file_name = table->file_name; + node->line_no = table->line_no; + + node->link = pnode[0]; pnode[0] = node; table->nodes++; @@ -494,6 +473,26 @@ } } + + FT_BASE_DEF( FT_Error ) + FT_Alloc_Debug( FT_Memory memory, + FT_Long size, + void* *P, + const char* file_name, + FT_Long line_no ) + { + FT_MemTable table = memory->user; + + if ( table ) + { + table->file_name = file_name; + table->line_no = line_no; + } + return FT_Alloc( memory, size, P ); + } + + + #else /* !FT_DEBUG_MEMORY */ /* ansi C doesn't like empty source files */