diff --git a/libtcc.c b/libtcc.c index d6576b90..1f896f26 100644 --- a/libtcc.c +++ b/libtcc.c @@ -69,10 +69,6 @@ ST_DATA struct TCCState *tcc_state; TCC_SEM(static tcc_compile_sem); -#ifdef MEM_DEBUG -static int nb_states; -#endif - /********************************************************/ #ifdef _WIN32 ST_FUNC char *normalize_slashes(char *path) @@ -324,9 +320,11 @@ struct mem_debug_header { typedef struct mem_debug_header mem_debug_header_t; +TCC_SEM(static mem_sem); static mem_debug_header_t *mem_debug_chain; static unsigned mem_cur_size; static unsigned mem_max_size; +static int nb_states; static mem_debug_header_t *malloc_check(void *ptr, const char *msg) { @@ -362,15 +360,16 @@ PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line) strncpy(header->file_name, file + (ofs > 0 ? ofs : 0), MEM_DEBUG_FILE_LEN); header->file_name[MEM_DEBUG_FILE_LEN] = 0; + WAIT_SEM(&mem_sem); header->next = mem_debug_chain; header->prev = NULL; if (header->next) header->next->prev = header; mem_debug_chain = header; - mem_cur_size += size; if (mem_cur_size > mem_max_size) mem_max_size = mem_cur_size; + POST_SEM(&mem_sem); return MEM_USER_PTR(header); } @@ -381,6 +380,8 @@ PUB_FUNC void tcc_free_debug(void *ptr) if (!ptr) return; header = malloc_check(ptr, "tcc_free"); + + WAIT_SEM(&mem_sem); mem_cur_size -= header->size; header->size = (unsigned)-1; if (header->next) @@ -389,6 +390,7 @@ PUB_FUNC void tcc_free_debug(void *ptr) header->prev->next = header->next; if (header == mem_debug_chain) mem_debug_chain = header->next; + POST_SEM(&mem_sem); free(header); } @@ -407,6 +409,8 @@ PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file if (!ptr) return tcc_malloc_debug(size, file, line); header = malloc_check(ptr, "tcc_realloc"); + + WAIT_SEM(&mem_sem); mem_cur_size -= header->size; mem_debug_chain_update = (header == mem_debug_chain); header = realloc(header, sizeof(mem_debug_header_t) + size); @@ -423,6 +427,8 @@ PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file mem_cur_size += size; if (mem_cur_size > mem_max_size) mem_max_size = mem_cur_size; + POST_SEM(&mem_sem); + return MEM_USER_PTR(header); } @@ -434,10 +440,13 @@ PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line) return ptr; } -PUB_FUNC void tcc_memcheck(void) +PUB_FUNC void tcc_memcheck(int d) { - if (mem_cur_size) { + WAIT_SEM(&mem_sem); + nb_states += d; + if (0 == nb_states && mem_cur_size) { mem_debug_header_t *header = mem_debug_chain; + fflush(stdout); fprintf(stderr, "MEM_DEBUG: mem_leak= %d bytes, mem_max_size= %d bytes\n", mem_cur_size, mem_max_size); while (header) { @@ -445,10 +454,14 @@ PUB_FUNC void tcc_memcheck(void) header->file_name, header->line_num, header->size); header = header->next; } + fflush(stderr); + mem_cur_size = 0; + mem_debug_chain = NULL; #if MEM_DEBUG-0 == 2 exit(2); #endif } + POST_SEM(&mem_sem); } #endif /* MEM_DEBUG */ @@ -785,7 +798,7 @@ LIBTCCAPI TCCState *tcc_new(void) if (!s) return NULL; #ifdef MEM_DEBUG - ++nb_states; + tcc_memcheck(1); #endif #undef gnu_ext @@ -862,8 +875,7 @@ LIBTCCAPI void tcc_delete(TCCState *s1) tcc_free(s1->dState); tcc_free(s1); #ifdef MEM_DEBUG - if (0 == --nb_states) - tcc_memcheck(); + tcc_memcheck(-1); #endif } diff --git a/tccdbg.c b/tccdbg.c index f63ab4b7..18c2cb10 100644 --- a/tccdbg.c +++ b/tccdbg.c @@ -889,8 +889,12 @@ ST_FUNC void tcc_debug_start(TCCState *s1) /* put end of translation unit info */ ST_FUNC void tcc_debug_end(TCCState *s1) { - if (!s1->do_debug) + if (!s1->do_debug || debug_next_type == 0) return; + + if (debug_info_root) + tcc_debug_funcend(s1, 0); /* free stuff in case of errors */ + if (s1->dwarf) { int i, j; int start_aranges; @@ -1019,6 +1023,7 @@ ST_FUNC void tcc_debug_end(TCCState *s1) text_section->data_offset, text_section, section_sym); } tcc_free(debug_hash); + debug_next_type = 0; } static BufferedFile* put_new_file(TCCState *s1) @@ -1920,6 +1925,7 @@ ST_FUNC void tcc_debug_funcend(TCCState *s1, int size) { tcc_debug_finish (s1, debug_info_root); } + debug_info_root = 0; } diff --git a/tccgen.c b/tccgen.c index bdbff99f..c7e8d136 100644 --- a/tccgen.c +++ b/tccgen.c @@ -401,6 +401,7 @@ ST_FUNC int tccgen_compile(TCCState *s1) ST_FUNC void tccgen_finish(TCCState *s1) { + tcc_debug_end(s1); /* just in case of errors: free memory */ cstr_free(&initstr); free_inline_functions(s1); sym_pop(&global_stack, NULL, 0);