History

a new version of the MEM_DEBUG

seyko committed 11 years ago

Commit 121e95d1 parent a98fd132 files · +195 −30Browse files

Unified · Split

2 files
  1. libtcc.c +180 −25
  2. tcc.h +15 −5
libtcc.c+180−25
@@ -198,17 +198,10 @@ PUB_FUNC char *tcc_fileextension (const char *name) · 197 unmodified lines
198198 #undef malloc
199199 #undef realloc
200200
201−#ifdef MEM_DEBUG
202−ST_DATA int mem_cur_size;
203−ST_DATA int mem_max_size;
204−unsigned malloc_usable_size(void*);
205−#endif
201+#ifndef MEM_DEBUG
206202
207203 PUB_FUNC void tcc_free(void *ptr)
208204 {
209−#ifdef MEM_DEBUG
210− mem_cur_size -= malloc_usable_size(ptr);
211−#endif
212205 free(ptr);
213206 }
214207
@@ -218,11 +211,6 @@ PUB_FUNC void *tcc_malloc(unsigned long size) · 3 unmodified lines
218211 ptr = malloc(size);
219212 if (!ptr && size)
220213 tcc_error("memory full (malloc)");
221−#ifdef MEM_DEBUG
222− mem_cur_size += malloc_usable_size(ptr);
223− if (mem_cur_size > mem_max_size)
224− mem_max_size = mem_cur_size;
225−#endif
226214 return ptr;
227215 }
228216
@@ -237,18 +225,9 @@ PUB_FUNC void *tcc_mallocz(unsigned long size) · 8 unmodified lines
237225 PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size)
238226 {
239227 void *ptr1;
240−#ifdef MEM_DEBUG
241− mem_cur_size -= malloc_usable_size(ptr);
242−#endif
243228 ptr1 = realloc(ptr, size);
244229 if (!ptr1 && size)
245230 tcc_error("memory full (realloc)");
246−#ifdef MEM_DEBUG
247− /* NOTE: count not correct if alloc error, but not critical */
248− mem_cur_size += malloc_usable_size(ptr1);
249− if (mem_cur_size > mem_max_size)
250− mem_max_size = mem_cur_size;
251−#endif
252231 return ptr1;
253232 }
254233
@@ -262,11 +241,187 @@ PUB_FUNC char *tcc_strdup(const char *str) · 7 unmodified lines
262241
263242 PUB_FUNC void tcc_memstats(void)
264243 {
265−#ifdef MEM_DEBUG
266− printf("memory: %d bytes, max = %d bytes\n", mem_cur_size, mem_max_size);
267−#endif
268244 }
269245
246+#else
247+
248+#define MEM_DEBUG_MAGIC1 0xFEEDDEB1
249+#define MEM_DEBUG_MAGIC2 0xFEEDDEB2
250+#define MEM_DEBUG_FILE_LEN 15
251+
252+struct mem_debug_header {
253+ size_t magic1;
254+ size_t size;
255+ struct mem_debug_header *prev;
256+ struct mem_debug_header *next;
257+ size_t line_num;
258+ char file_name[MEM_DEBUG_FILE_LEN + 1];
259+ size_t magic2;
260+};
261+
262+typedef struct mem_debug_header mem_debug_header_t;
263+
264+static mem_debug_header_t *mem_debug_chain;
265+static size_t mem_cur_size;
266+static size_t mem_max_size;
267+
268+PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line)
269+{
270+ void *ptr;
271+ mem_debug_header_t *header;
272+
273+ ptr = malloc(sizeof(mem_debug_header_t) + size);
274+ if (!ptr)
275+ tcc_error("memory full (malloc)");
276+
277+ mem_cur_size += size;
278+ if (mem_cur_size > mem_max_size)
279+ mem_max_size = mem_cur_size;
280+
281+ header = (mem_debug_header_t *)ptr;
282+
283+ header->magic1 = MEM_DEBUG_MAGIC1;
284+ header->magic2 = MEM_DEBUG_MAGIC2;
285+ header->size = size;
286+ header->line_num = line;
287+
288+ strncpy(header->file_name, file, MEM_DEBUG_FILE_LEN);
289+ header->file_name[MEM_DEBUG_FILE_LEN] = 0;
290+
291+ header->next = mem_debug_chain;
292+ header->prev = NULL;
293+
294+ if (header->next)
295+ header->next->prev = header;
296+
297+ mem_debug_chain = header;
298+
299+ ptr = (char *)ptr + sizeof(mem_debug_header_t);
300+ return ptr;
301+}
302+
303+PUB_FUNC void tcc_free_debug(void *ptr)
304+{
305+ mem_debug_header_t *header;
306+
307+ if (!ptr)
308+ return;
309+
310+ ptr = (char *)ptr - sizeof(mem_debug_header_t);
311+ header = (mem_debug_header_t *)ptr;
312+ if (header->magic1 != MEM_DEBUG_MAGIC1 ||
313+ header->magic2 != MEM_DEBUG_MAGIC2 ||
314+ header->size == (size_t)-1 )
315+ {
316+ tcc_error("tcc_free check failed");
317+ }
318+
319+ mem_cur_size -= header->size;
320+ header->size = (size_t)-1;
321+
322+ if (header->next)
323+ header->next->prev = header->prev;
324+
325+ if (header->prev)
326+ header->prev->next = header->next;
327+
328+ if (header == mem_debug_chain)
329+ mem_debug_chain = header->next;
330+
331+ free(ptr);
332+}
333+
334+
335+PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line)
336+{
337+ void *ptr;
338+ ptr = tcc_malloc_debug(size,file,line);
339+ memset(ptr, 0, size);
340+ return ptr;
341+}
342+
343+PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file, int line)
344+{
345+ mem_debug_header_t *header;
346+ int mem_debug_chain_update = 0;
347+
348+ if (!ptr) {
349+ ptr = tcc_malloc_debug(size, file, line);
350+ return ptr;
351+ }
352+
353+ ptr = (char *)ptr - sizeof(mem_debug_header_t);
354+ header = (mem_debug_header_t *)ptr;
355+ if (header->magic1 != MEM_DEBUG_MAGIC1 ||
356+ header->magic2 != MEM_DEBUG_MAGIC2 ||
357+ header->size == (size_t)-1 )
358+ {
359+ check_error:
360+ tcc_error("tcc_realloc check failed");
361+ }
362+
363+ mem_debug_chain_update = (header == mem_debug_chain);
364+
365+ mem_cur_size -= header->size;
366+ ptr = realloc(ptr, sizeof(mem_debug_header_t) + size);
367+ if (!ptr)
368+ tcc_error("memory full (realloc)");
369+
370+ header = (mem_debug_header_t *)ptr;
371+ if (header->magic1 != MEM_DEBUG_MAGIC1 ||
372+ header->magic2 != MEM_DEBUG_MAGIC2)
373+ {
374+ goto check_error;
375+ }
376+
377+ mem_cur_size += size;
378+ if (mem_cur_size > mem_max_size)
379+ mem_max_size = mem_cur_size;
380+
381+ header->size = size;
382+ if (header->next)
383+ header->next->prev = header;
384+
385+ if (header->prev)
386+ header->prev->next = header;
387+
388+ if (mem_debug_chain_update)
389+ mem_debug_chain = header;
390+
391+ ptr = (char *)ptr + sizeof(mem_debug_header_t);
392+ return ptr;
393+}
394+
395+PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line)
396+{
397+ char *ptr;
398+ ptr = tcc_malloc_debug(strlen(str) + 1, file, line);
399+ strcpy(ptr, str);
400+ return ptr;
401+}
402+
403+PUB_FUNC void tcc_memstats(void)
404+{
405+ if (mem_cur_size) {
406+ mem_debug_header_t *header = mem_debug_chain;
407+
408+ fprintf(stderr, "MEM_DEBUG: mem_leak= %d bytes, mem_max_size= %d bytes\n",
409+ mem_cur_size, mem_max_size);
410+
411+ while (header) {
412+ fprintf(stderr, " file %s, line %u: %u bytes\n",
413+ header->file_name, header->line_num, header->size);
414+ header = header->next;
415+ }
416+ }
417+}
418+
419+#undef MEM_DEBUG_MAGIC1
420+#undef MEM_DEBUG_MAGIC2
421+#undef MEM_DEBUG_FILE_LEN
422+
423+#endif
424+
270425 #define free(p) use_tcc_free(p)
271426 #define malloc(s) use_tcc_malloc(s)
272427 #define realloc(p, s) use_tcc_realloc(p, s)
tcc.h+15−5
@@ -1052,11 +1052,6 @@ ST_DATA int tcc_ext; · 1051 unmodified lines
10521052 /* XXX: get rid of this ASAP */
10531053 ST_DATA struct TCCState *tcc_state;
10541054
1055−#ifdef MEM_DEBUG
1056−ST_DATA int mem_cur_size;
1057−ST_DATA int mem_max_size;
1058−#endif
1059−
10601055 #define AFF_PRINT_ERROR 0x0001 /* print error if file not found */
10611056 #define AFF_REFERENCED_DLL 0x0002 /* load a referenced dll from another dll */
10621057 #define AFF_PREPROCESS 0x0004 /* preprocess file */
@@ -1067,11 +1062,26 @@ PUB_FUNC char *pstrcat(char *buf, int buf_size, const char *s); · 4 unmodified lines
10671062 PUB_FUNC char *pstrncpy(char *out, const char *in, size_t num);
10681063 PUB_FUNC char *tcc_basename(const char *name);
10691064 PUB_FUNC char *tcc_fileextension (const char *name);
1065+
1066+#ifndef MEM_DEBUG
10701067 PUB_FUNC void tcc_free(void *ptr);
10711068 PUB_FUNC void *tcc_malloc(unsigned long size);
10721069 PUB_FUNC void *tcc_mallocz(unsigned long size);
10731070 PUB_FUNC void *tcc_realloc(void *ptr, unsigned long size);
10741071 PUB_FUNC char *tcc_strdup(const char *str);
1072+#else
1073+#define tcc_free(ptr) tcc_free_debug(ptr)
1074+#define tcc_malloc(size) tcc_malloc_debug(size, __FILE__, __LINE__)
1075+#define tcc_mallocz(size) tcc_mallocz_debug(size, __FILE__, __LINE__)
1076+#define tcc_realloc(ptr,size) tcc_realloc_debug(ptr, size, __FILE__, __LINE__)
1077+#define tcc_strdup(str) tcc_strdup_debug(str, __FILE__, __LINE__)
1078+PUB_FUNC void tcc_free_debug(void *ptr);
1079+PUB_FUNC void *tcc_malloc_debug(unsigned long size, const char *file, int line);
1080+PUB_FUNC void *tcc_mallocz_debug(unsigned long size, const char *file, int line);
1081+PUB_FUNC void *tcc_realloc_debug(void *ptr, unsigned long size, const char *file, int line);
1082+PUB_FUNC char *tcc_strdup_debug(const char *str, const char *file, int line);
1083+#endif
1084+
10751085 #define free(p) use_tcc_free(p)
10761086 #define malloc(s) use_tcc_malloc(s)
10771087 #define realloc(p, s) use_tcc_realloc(p, s)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t