mirror of
https://github.com/mirror/tinycc.git
synced 2025-01-15 05:20:06 +08:00
a new version of the MEM_DEBUG
This commit is contained in:
parent
a98fd13090
commit
121e95d115
205
libtcc.c
205
libtcc.c
@ -198,17 +198,10 @@ PUB_FUNC char *tcc_fileextension (const char *name)
|
|||||||
#undef malloc
|
#undef malloc
|
||||||
#undef realloc
|
#undef realloc
|
||||||
|
|
||||||
#ifdef MEM_DEBUG
|
#ifndef MEM_DEBUG
|
||||||
ST_DATA int mem_cur_size;
|
|
||||||
ST_DATA int mem_max_size;
|
|
||||||
unsigned malloc_usable_size(void*);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
PUB_FUNC void tcc_free(void *ptr)
|
PUB_FUNC void tcc_free(void *ptr)
|
||||||
{
|
{
|
||||||
#ifdef MEM_DEBUG
|
|
||||||
mem_cur_size -= malloc_usable_size(ptr);
|
|
||||||
#endif
|
|
||||||
free(ptr);
|
free(ptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,11 +211,6 @@ PUB_FUNC void *tcc_malloc(unsigned long size)
|
|||||||
ptr = malloc(size);
|
ptr = malloc(size);
|
||||||
if (!ptr && size)
|
if (!ptr && size)
|
||||||
tcc_error("memory full (malloc)");
|
tcc_error("memory full (malloc)");
|
||||||
#ifdef MEM_DEBUG
|
|
||||||
mem_cur_size += malloc_usable_size(ptr);
|
|
||||||
if (mem_cur_size > mem_max_size)
|
|
||||||
mem_max_size = mem_cur_size;
|
|
||||||
#endif
|
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -237,18 +225,9 @@ PUB_FUNC void *tcc_mallocz(unsigned long size)
|
|||||||
PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size)
|
PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size)
|
||||||
{
|
{
|
||||||
void *ptr1;
|
void *ptr1;
|
||||||
#ifdef MEM_DEBUG
|
|
||||||
mem_cur_size -= malloc_usable_size(ptr);
|
|
||||||
#endif
|
|
||||||
ptr1 = realloc(ptr, size);
|
ptr1 = realloc(ptr, size);
|
||||||
if (!ptr1 && size)
|
if (!ptr1 && size)
|
||||||
tcc_error("memory full (realloc)");
|
tcc_error("memory full (realloc)");
|
||||||
#ifdef MEM_DEBUG
|
|
||||||
/* NOTE: count not correct if alloc error, but not critical */
|
|
||||||
mem_cur_size += malloc_usable_size(ptr1);
|
|
||||||
if (mem_cur_size > mem_max_size)
|
|
||||||
mem_max_size = mem_cur_size;
|
|
||||||
#endif
|
|
||||||
return ptr1;
|
return ptr1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,11 +241,187 @@ PUB_FUNC char *tcc_strdup(const char *str)
|
|||||||
|
|
||||||
PUB_FUNC void tcc_memstats(void)
|
PUB_FUNC void tcc_memstats(void)
|
||||||
{
|
{
|
||||||
#ifdef MEM_DEBUG
|
|
||||||
printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define MEM_DEBUG_MAGIC1 0xFEEDDEB1
|
||||||
|
#define MEM_DEBUG_MAGIC2 0xFEEDDEB2
|
||||||
|
#define MEM_DEBUG_FILE_LEN 15
|
||||||
|
|
||||||
|
struct mem_debug_header {
|
||||||
|
size_t magic1;
|
||||||
|
size_t size;
|
||||||
|
struct mem_debug_header *prev;
|
||||||
|
struct mem_debug_header *next;
|
||||||
|
size_t line_num;
|
||||||
|
char file_name[MEM_DEBUG_FILE_LEN + 1];
|
||||||
|
size_t magic2;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct mem_debug_header mem_debug_header_t;
|
||||||
|
|
||||||
|
static mem_debug_header_t *mem_debug_chain;
|
||||||
|
static size_t mem_cur_size;
|
||||||
|
static size_t mem_max_size;
|
||||||
|
|
||||||
|
PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line)
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
mem_debug_header_t *header;
|
||||||
|
|
||||||
|
ptr = malloc(sizeof(mem_debug_header_t) + size);
|
||||||
|
if (!ptr)
|
||||||
|
tcc_error("memory full (malloc)");
|
||||||
|
|
||||||
|
mem_cur_size += size;
|
||||||
|
if (mem_cur_size > mem_max_size)
|
||||||
|
mem_max_size = mem_cur_size;
|
||||||
|
|
||||||
|
header = (mem_debug_header_t *)ptr;
|
||||||
|
|
||||||
|
header->magic1 = MEM_DEBUG_MAGIC1;
|
||||||
|
header->magic2 = MEM_DEBUG_MAGIC2;
|
||||||
|
header->size = size;
|
||||||
|
header->line_num = line;
|
||||||
|
|
||||||
|
strncpy(header->file_name, file, MEM_DEBUG_FILE_LEN);
|
||||||
|
header->file_name[MEM_DEBUG_FILE_LEN] = 0;
|
||||||
|
|
||||||
|
header->next = mem_debug_chain;
|
||||||
|
header->prev = NULL;
|
||||||
|
|
||||||
|
if (header->next)
|
||||||
|
header->next->prev = header;
|
||||||
|
|
||||||
|
mem_debug_chain = header;
|
||||||
|
|
||||||
|
ptr = (char *)ptr + sizeof(mem_debug_header_t);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
PUB_FUNC void tcc_free_debug(void *ptr)
|
||||||
|
{
|
||||||
|
mem_debug_header_t *header;
|
||||||
|
|
||||||
|
if (!ptr)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ptr = (char *)ptr - sizeof(mem_debug_header_t);
|
||||||
|
header = (mem_debug_header_t *)ptr;
|
||||||
|
if (header->magic1 != MEM_DEBUG_MAGIC1 ||
|
||||||
|
header->magic2 != MEM_DEBUG_MAGIC2 ||
|
||||||
|
header->size == (size_t)-1 )
|
||||||
|
{
|
||||||
|
tcc_error("tcc_free check failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
mem_cur_size -= header->size;
|
||||||
|
header->size = (size_t)-1;
|
||||||
|
|
||||||
|
if (header->next)
|
||||||
|
header->next->prev = header->prev;
|
||||||
|
|
||||||
|
if (header->prev)
|
||||||
|
header->prev->next = header->next;
|
||||||
|
|
||||||
|
if (header == mem_debug_chain)
|
||||||
|
mem_debug_chain = header->next;
|
||||||
|
|
||||||
|
free(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line)
|
||||||
|
{
|
||||||
|
void *ptr;
|
||||||
|
ptr = tcc_malloc_debug(size,file,line);
|
||||||
|
memset(ptr, 0, size);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file, int line)
|
||||||
|
{
|
||||||
|
mem_debug_header_t *header;
|
||||||
|
int mem_debug_chain_update = 0;
|
||||||
|
|
||||||
|
if (!ptr) {
|
||||||
|
ptr = tcc_malloc_debug(size, file, line);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
ptr = (char *)ptr - sizeof(mem_debug_header_t);
|
||||||
|
header = (mem_debug_header_t *)ptr;
|
||||||
|
if (header->magic1 != MEM_DEBUG_MAGIC1 ||
|
||||||
|
header->magic2 != MEM_DEBUG_MAGIC2 ||
|
||||||
|
header->size == (size_t)-1 )
|
||||||
|
{
|
||||||
|
check_error:
|
||||||
|
tcc_error("tcc_realloc check failed");
|
||||||
|
}
|
||||||
|
|
||||||
|
mem_debug_chain_update = (header == mem_debug_chain);
|
||||||
|
|
||||||
|
mem_cur_size -= header->size;
|
||||||
|
ptr = realloc(ptr, sizeof(mem_debug_header_t) + size);
|
||||||
|
if (!ptr)
|
||||||
|
tcc_error("memory full (realloc)");
|
||||||
|
|
||||||
|
header = (mem_debug_header_t *)ptr;
|
||||||
|
if (header->magic1 != MEM_DEBUG_MAGIC1 ||
|
||||||
|
header->magic2 != MEM_DEBUG_MAGIC2)
|
||||||
|
{
|
||||||
|
goto check_error;
|
||||||
|
}
|
||||||
|
|
||||||
|
mem_cur_size += size;
|
||||||
|
if (mem_cur_size > mem_max_size)
|
||||||
|
mem_max_size = mem_cur_size;
|
||||||
|
|
||||||
|
header->size = size;
|
||||||
|
if (header->next)
|
||||||
|
header->next->prev = header;
|
||||||
|
|
||||||
|
if (header->prev)
|
||||||
|
header->prev->next = header;
|
||||||
|
|
||||||
|
if (mem_debug_chain_update)
|
||||||
|
mem_debug_chain = header;
|
||||||
|
|
||||||
|
ptr = (char *)ptr + sizeof(mem_debug_header_t);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line)
|
||||||
|
{
|
||||||
|
char *ptr;
|
||||||
|
ptr = tcc_malloc_debug(strlen(str) + 1, file, line);
|
||||||
|
strcpy(ptr, str);
|
||||||
|
return ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
PUB_FUNC void tcc_memstats(void)
|
||||||
|
{
|
||||||
|
if (mem_cur_size) {
|
||||||
|
mem_debug_header_t *header = mem_debug_chain;
|
||||||
|
|
||||||
|
fprintf(stderr, "MEM_DEBUG: mem_leak= %d bytes, mem_max_size= %d bytes\n",
|
||||||
|
mem_cur_size, mem_max_size);
|
||||||
|
|
||||||
|
while (header) {
|
||||||
|
fprintf(stderr, " file %s, line %u: %u bytes\n",
|
||||||
|
header->file_name, header->line_num, header->size);
|
||||||
|
header = header->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#undef MEM_DEBUG_MAGIC1
|
||||||
|
#undef MEM_DEBUG_MAGIC2
|
||||||
|
#undef MEM_DEBUG_FILE_LEN
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#define free(p) use_tcc_free(p)
|
#define free(p) use_tcc_free(p)
|
||||||
#define malloc(s) use_tcc_malloc(s)
|
#define malloc(s) use_tcc_malloc(s)
|
||||||
#define realloc(p, s) use_tcc_realloc(p, s)
|
#define realloc(p, s) use_tcc_realloc(p, s)
|
||||||
|
20
tcc.h
20
tcc.h
@ -1052,11 +1052,6 @@ ST_DATA int tcc_ext;
|
|||||||
/* XXX: get rid of this ASAP */
|
/* XXX: get rid of this ASAP */
|
||||||
ST_DATA struct TCCState *tcc_state;
|
ST_DATA struct TCCState *tcc_state;
|
||||||
|
|
||||||
#ifdef MEM_DEBUG
|
|
||||||
ST_DATA int mem_cur_size;
|
|
||||||
ST_DATA int mem_max_size;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
|
#define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
|
||||||
#define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
|
#define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
|
||||||
#define AFF_PREPROCESS 0x0004 /* preprocess file */
|
#define AFF_PREPROCESS 0x0004 /* preprocess file */
|
||||||
@ -1067,11 +1062,26 @@ PUB_FUNC char *pstrcat(char *buf, int buf_size, const char *s);
|
|||||||
PUB_FUNC char *pstrncpy(char *out, const char *in, size_t num);
|
PUB_FUNC char *pstrncpy(char *out, const char *in, size_t num);
|
||||||
PUB_FUNC char *tcc_basename(const char *name);
|
PUB_FUNC char *tcc_basename(const char *name);
|
||||||
PUB_FUNC char *tcc_fileextension (const char *name);
|
PUB_FUNC char *tcc_fileextension (const char *name);
|
||||||
|
|
||||||
|
#ifndef MEM_DEBUG
|
||||||
PUB_FUNC void tcc_free(void *ptr);
|
PUB_FUNC void tcc_free(void *ptr);
|
||||||
PUB_FUNC void *tcc_malloc(unsigned long size);
|
PUB_FUNC void *tcc_malloc(unsigned long size);
|
||||||
PUB_FUNC void *tcc_mallocz(unsigned long size);
|
PUB_FUNC void *tcc_mallocz(unsigned long size);
|
||||||
PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size);
|
PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size);
|
||||||
PUB_FUNC char *tcc_strdup(const char *str);
|
PUB_FUNC char *tcc_strdup(const char *str);
|
||||||
|
#else
|
||||||
|
#define tcc_free(ptr) tcc_free_debug(ptr)
|
||||||
|
#define tcc_malloc(size) tcc_malloc_debug(size, __FILE__, __LINE__)
|
||||||
|
#define tcc_mallocz(size) tcc_mallocz_debug(size, __FILE__, __LINE__)
|
||||||
|
#define tcc_realloc(ptr,size) tcc_realloc_debug(ptr, size, __FILE__, __LINE__)
|
||||||
|
#define tcc_strdup(str) tcc_strdup_debug(str, __FILE__, __LINE__)
|
||||||
|
PUB_FUNC void tcc_free_debug(void *ptr);
|
||||||
|
PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line);
|
||||||
|
PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line);
|
||||||
|
PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file, int line);
|
||||||
|
PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line);
|
||||||
|
#endif
|
||||||
|
|
||||||
#define free(p) use_tcc_free(p)
|
#define free(p) use_tcc_free(p)
|
||||||
#define malloc(s) use_tcc_malloc(s)
|
#define malloc(s) use_tcc_malloc(s)
|
||||||
#define realloc(p, s) use_tcc_realloc(p, s)
|
#define realloc(p, s) use_tcc_realloc(p, s)
|
||||||
|
Loading…
Reference in New Issue
Block a user