memory: several fixes

Set pointers to NULL after free() to help force out memory handling errors
Add some extra memory / resource tracking to try and chase out latent
bugs / leaks. Fixed a couple of memory traces that were misreporting
This commit is contained in:
Ian Clowes 2022-01-05 16:16:07 +01:00 committed by Nick Hainke
parent b0aa1c0d15
commit 4df81328d1

View file

@ -4,6 +4,7 @@
#include <string.h> #include <string.h>
#include <inttypes.h> #include <inttypes.h>
#include "utils.h"
#include "memory_utils.h" #include "memory_utils.h"
#define DAWN_MEM_FILENAME_LEN 20 #define DAWN_MEM_FILENAME_LEN 20
@ -54,10 +55,6 @@ void* dawn_memory_register(enum dawn_memop type, char* file, int line, size_t si
struct mem_list* this_log = NULL; struct mem_list* this_log = NULL;
char type_c = '?'; char type_c = '?';
// Ignore over enthusiastic effort to register a failed allocation
if (ptr == NULL)
return ret;
switch (type) switch (type)
{ {
case DAWN_MALLOC: case DAWN_MALLOC:
@ -73,10 +70,19 @@ void* dawn_memory_register(enum dawn_memop type, char* file, int line, size_t si
type_c = 'X'; type_c = 'X';
break; break;
default: default:
printf("mem-audit: Unexpected memory op tag!\n"); fprintf(stderr,"mem-audit: Unexpected memory op tag!\n");
break; break;
} }
// Note effort to register a failed allocation (other code probably wrong as well)
if (ptr == NULL)
{
char* xfile = strrchr(file, '/');
fprintf(stderr,"mem-audit: attempting to register failed allocation (%c@%s:%d)...\n", type_c, xfile ? xfile + 1 : file, line);
return ret;
}
// Insert to linked list with ascending memory reference // Insert to linked list with ascending memory reference
struct mem_list** ipos = &mem_base; struct mem_list** ipos = &mem_base;
while (*ipos != NULL && (*ipos)->ptr < ptr) while (*ipos != NULL && (*ipos)->ptr < ptr)
@ -84,7 +90,9 @@ void* dawn_memory_register(enum dawn_memop type, char* file, int line, size_t si
if (*ipos != NULL && (*ipos)->ptr == ptr) if (*ipos != NULL && (*ipos)->ptr == ptr)
{ {
printf("mem-audit: attempting to register memory already registered (%c@%s:%d)...\n", type_c, file, line); char* xfile = strrchr(file, '/');
fprintf(stderr,"mem-audit: attempted to register memory already registered (%c@%s:%d)...\n", type_c, xfile ? xfile + 1 : file, line);
} }
else else
{ {
@ -92,18 +100,19 @@ void* dawn_memory_register(enum dawn_memop type, char* file, int line, size_t si
if (this_log == NULL) if (this_log == NULL)
{ {
printf("mem-audit: Oh the irony! malloc() failed in dawn_memory_register()!\n"); fprintf(stderr,"mem-audit: Oh the irony! malloc() failed in dawn_memory_register()!\n");
} }
else else
{ {
// Just use filename - no path
char *xfile = strrchr(file, '/');
fprintf(stdout,"mem-audit: registering memory (%c@%s:%d)...\n", type_c, xfile ? xfile + 1 : file, line);
this_log->next_mem = *ipos; this_log->next_mem = *ipos;
*ipos = this_log; *ipos = this_log;
// Just use filename - no path if (xfile != NULL)
file = strrchr(file, '/'); strncpy(this_log->file, xfile + 1, DAWN_MEM_FILENAME_LEN);
if (file != NULL)
strncpy(this_log->file, file + 1, DAWN_MEM_FILENAME_LEN);
else else
strncpy(this_log->file, "?? UNKNOWN ??", DAWN_MEM_FILENAME_LEN); strncpy(this_log->file, "?? UNKNOWN ??", DAWN_MEM_FILENAME_LEN);
@ -121,38 +130,26 @@ void* dawn_memory_register(enum dawn_memop type, char* file, int line, size_t si
void dawn_memory_unregister(enum dawn_memop type, char* file, int line, void* ptr) void dawn_memory_unregister(enum dawn_memop type, char* file, int line, void* ptr)
{ {
struct mem_list** mem = &mem_base; struct mem_list** mem = &mem_base;
char type_c = '?';
while (*mem != NULL && (*mem)->ptr < ptr) while (*mem != NULL && (*mem)->ptr < ptr)
{ {
mem = &((*mem)->next_mem); mem = &((*mem)->next_mem);
} }
switch (type) char* xfile = strrchr(file, '/');
{
case DAWN_FREE:
type_c = 'F';
break;
case DAWN_MEMUNREG:
type_c = 'U';
break;
case DAWN_REALLOC:
type_c = 'R';
break;
default:
printf("mem-audit: Unexpected memory op tag!\n");
break;
}
if (*mem != NULL && (*mem)->ptr == ptr) if (*mem != NULL && (*mem)->ptr == ptr)
{ {
// Just use filename - no path
fprintf(stdout,"mem-audit: unregistering memory (%s:%d -> %c@%s:%d)...\n", xfile ? xfile + 1 : file, line, (*mem)->type, (*mem)->file, (*mem)->line);
struct mem_list* tmp = *mem; struct mem_list* tmp = *mem;
*mem = tmp->next_mem; *mem = tmp->next_mem;
free(tmp); free(tmp);
} }
else else
{ {
printf("mem-audit: Releasing (%c) memory we hadn't registered (%s:%d)...\n", type_c, file, line); fprintf(stderr,"mem-audit: Releasing memory we hadn't registered (%s:%d)...\n", xfile ? xfile + 1 : file, line);
} }
return; return;
@ -171,10 +168,10 @@ void dawn_memory_audit()
{ {
size_t total = 0; size_t total = 0;
printf("mem-audit: Currently recorded allocations...\n"); fprintf(stdout,"mem-audit: Currently recorded allocations...\n");
for (struct mem_list* mem = mem_base; mem != NULL; mem = mem->next_mem) for (struct mem_list* mem = mem_base; mem != NULL; mem = mem->next_mem)
{ {
printf("mem-audit: %8" PRIu64 "=%c - %s@%d: %zu\n", mem->ref, mem->type, mem->file, mem->line, mem->size); fprintf(stdout,"mem-audit: %8" PRIu64 "=%c - %s@%d: %zu\n", mem->ref, mem->type, mem->file, mem->line, mem->size);
total += mem->size; total += mem->size;
} }
@ -185,5 +182,5 @@ size_t total = 0;
suffix = "kbytes"; suffix = "kbytes";
} }
printf("mem-audit: [End of list: %zu %s]\n", total, suffix); fprintf(stdout,"mem-audit: [End of list: %zu %s]\n", total, suffix);
} }