mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2025-12-28 01:40:08 +01:00
gallium: Attribute realloc leaks to the first malloc call.
This commit is contained in:
parent
c95dcc4962
commit
bc56e87ce1
2 changed files with 68 additions and 11 deletions
|
|
@ -73,6 +73,25 @@ static struct list_head list = { &list, &list };
|
|||
static unsigned long last_no = 0;
|
||||
|
||||
|
||||
static INLINE struct debug_memory_header *
|
||||
header_from_data(void *data)
|
||||
{
|
||||
if(data)
|
||||
return (struct debug_memory_header *)((char *)data - sizeof(struct debug_memory_header));
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static INLINE void *
|
||||
data_from_header(struct debug_memory_header *hdr)
|
||||
{
|
||||
if(hdr)
|
||||
return (void *)((char *)hdr + sizeof(struct debug_memory_header));
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
void *
|
||||
debug_malloc(const char *file, unsigned line, const char *function,
|
||||
size_t size)
|
||||
|
|
@ -92,7 +111,7 @@ debug_malloc(const char *file, unsigned line, const char *function,
|
|||
|
||||
LIST_ADDTAIL(&hdr->head, &list);
|
||||
|
||||
return (void *)((char *)hdr + sizeof(*hdr));
|
||||
return data_from_header(hdr);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
@ -104,7 +123,7 @@ debug_free(const char *file, unsigned line, const char *function,
|
|||
if(!ptr)
|
||||
return;
|
||||
|
||||
hdr = (struct debug_memory_header *)((char *)ptr - sizeof(*hdr));
|
||||
hdr = header_from_data(ptr);
|
||||
if(hdr->magic != DEBUG_MEMORY_MAGIC) {
|
||||
debug_printf("%s:%u:%s: freeing bad or corrupted memory %p\n",
|
||||
file, line, function,
|
||||
|
|
@ -133,16 +152,46 @@ 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 );
|
||||
struct debug_memory_header *old_hdr, *new_hdr;
|
||||
void *new_ptr;
|
||||
|
||||
if(!old_ptr)
|
||||
return debug_malloc( file, line, function, new_size );
|
||||
|
||||
if(!new_size) {
|
||||
debug_free( file, line, function, old_ptr );
|
||||
return NULL;
|
||||
}
|
||||
|
||||
old_hdr = header_from_data(old_ptr);
|
||||
if(old_hdr->magic != DEBUG_MEMORY_MAGIC) {
|
||||
debug_printf("%s:%u:%s: reallocating bad or corrupted memory %p\n",
|
||||
file, line, function,
|
||||
old_ptr);
|
||||
debug_assert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* alloc new */
|
||||
new_hdr = real_malloc(sizeof(*new_hdr) + new_size);
|
||||
if(!new_hdr)
|
||||
return NULL;
|
||||
new_hdr->no = old_hdr->no;
|
||||
new_hdr->file = old_hdr->file;
|
||||
new_hdr->line = old_hdr->line;
|
||||
new_hdr->function = old_hdr->function;
|
||||
new_hdr->size = new_size;
|
||||
new_hdr->magic = DEBUG_MEMORY_MAGIC;
|
||||
LIST_REPLACE(&old_hdr->head, &new_hdr->head);
|
||||
|
||||
/* copy data */
|
||||
new_ptr = data_from_header(new_hdr);
|
||||
memcpy( new_ptr, old_ptr, old_size < new_size ? old_size : new_size );
|
||||
|
||||
/* free old */
|
||||
old_hdr->magic = 0;
|
||||
real_free(old_hdr);
|
||||
|
||||
debug_free( file, line, function, old_ptr );
|
||||
return new_ptr;
|
||||
}
|
||||
|
||||
|
|
@ -162,7 +211,7 @@ debug_memory_end(unsigned long start_no)
|
|||
struct debug_memory_header *hdr;
|
||||
void *ptr;
|
||||
hdr = LIST_ENTRY(struct debug_memory_header, entry, head);
|
||||
ptr = (void *)((char *)hdr + sizeof(*hdr));
|
||||
ptr = data_from_header(hdr);
|
||||
if(start_no <= hdr->no && hdr->no < last_no ||
|
||||
last_no < start_no && (hdr->no < last_no || start_no <= hdr->no))
|
||||
debug_printf("%s:%u:%s: %u bytes at %p not freed\n",
|
||||
|
|
|
|||
|
|
@ -70,6 +70,14 @@ struct list_head
|
|||
(__list)->prev = (__item); \
|
||||
} while(0)
|
||||
|
||||
#define LIST_REPLACE(__from, __to) \
|
||||
do { \
|
||||
(__to)->prev = (__from)->prev; \
|
||||
(__to)->next = (__from)->next; \
|
||||
(__from)->next->prev = (__to); \
|
||||
(__from)->prev->next = (__to); \
|
||||
} while (0)
|
||||
|
||||
#define LIST_DEL(__item) \
|
||||
do { \
|
||||
(__item)->prev->next = (__item)->next; \
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue