From 81b21b1fdbd587fc2ac9ea465bc945efa45ab7b4 Mon Sep 17 00:00:00 2001 From: Olivier Matz Date: Fri, 28 Oct 2016 16:13:25 +0200 Subject: [PATCH] debug malloc to track mem leaks --- lib/build/test | Bin 62432 -> 67320 bytes lib/ecoli_malloc.c | 32 ++++++---- lib/ecoli_malloc.h | 102 ++++++++++++++++--------------- lib/ecoli_test.c | 146 ++++++++++++++++++++++++++++++++++++++++++++- lib/ecoli_tk_int.c | 5 +- lib/ecoli_tk_or.c | 23 ++++--- lib/ecoli_tk_or.h | 2 + lib/ecoli_tk_seq.c | 41 +++++++------ 8 files changed, 258 insertions(+), 93 deletions(-) diff --git a/lib/build/test b/lib/build/test index 68efeb74356fe2fa3fc293875b7809a911c8cf2f..34b89acd1d6bc3223aadd48cbda8bda29fa99d76 100755 GIT binary patch literal 67320 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 literal 62432 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 diff --git a/lib/ecoli_malloc.c b/lib/ecoli_malloc.c index 11782a7..0bdbf21 100644 --- a/lib/ecoli_malloc.c +++ b/lib/ecoli_malloc.c @@ -47,17 +47,25 @@ int ec_malloc_register(ec_malloc_t usr_malloc, ec_free_t usr_free, return 0; } -void *__ec_malloc(size_t size) +void ec_malloc_unregister(void) { - return ec_malloc_handler.malloc(size); + ec_malloc_handler.malloc = NULL; + ec_malloc_handler.free = NULL; + ec_malloc_handler.realloc = NULL; } -void __ec_free(void *ptr) +void *__ec_malloc(size_t size, const char *file, unsigned int line) { - ec_malloc_handler.free(ptr); + return ec_malloc_handler.malloc(size, file, line); } -void *__ec_calloc(size_t nmemb, size_t size) +void __ec_free(void *ptr, const char *file, unsigned int line) +{ + ec_malloc_handler.free(ptr, file, line); +} + +void *__ec_calloc(size_t nmemb, size_t size, const char *file, + unsigned int line) { void *ptr; size_t total; @@ -68,7 +76,7 @@ void *__ec_calloc(size_t nmemb, size_t size) return NULL; } - ptr = __ec_malloc(total); + ptr = __ec_malloc(total, file, line); if (ptr == NULL) return NULL; @@ -76,17 +84,17 @@ void *__ec_calloc(size_t nmemb, size_t size) return ptr; } -void *__ec_realloc(void *ptr, size_t size) +void *__ec_realloc(void *ptr, size_t size, const char *file, unsigned int line) { - return ec_malloc_handler.realloc(ptr, size); + return ec_malloc_handler.realloc(ptr, size, file, line); } -char *__ec_strdup(const char *s) +char *__ec_strdup(const char *s, const char *file, unsigned int line) { size_t sz = strlen(s) + 1; char *s2; - s2 = __ec_malloc(sz); + s2 = __ec_malloc(sz, file, line); if (s2 == NULL) return NULL; @@ -95,12 +103,12 @@ char *__ec_strdup(const char *s) return s2; } -char *__ec_strndup(const char *s, size_t n) +char *__ec_strndup(const char *s, size_t n, const char *file, unsigned int line) { size_t sz = strnlen(s, n); char *s2; - s2 = __ec_malloc(sz + 1); + s2 = __ec_malloc(sz + 1, file, line); if (s2 == NULL) return NULL; diff --git a/lib/ecoli_malloc.h b/lib/ecoli_malloc.h index ddf1828..4c49649 100644 --- a/lib/ecoli_malloc.h +++ b/lib/ecoli_malloc.h @@ -30,9 +30,10 @@ #include -typedef void *(*ec_malloc_t)(size_t size); -typedef void (*ec_free_t)(void *ptr); -typedef void *(*ec_realloc_t)(void *ptr, size_t size); +typedef void *(*ec_malloc_t)(size_t size, const char *file, unsigned int line); +typedef void (*ec_free_t)(void *ptr, const char *file, unsigned int line); +typedef void *(*ec_realloc_t)(void *ptr, size_t size, const char *file, + unsigned int line); struct ec_malloc_handler { ec_malloc_t malloc; @@ -44,68 +45,71 @@ extern struct ec_malloc_handler ec_malloc_handler; int ec_malloc_register(ec_malloc_t usr_malloc, ec_free_t usr_free, ec_realloc_t usr_realloc); +void ec_malloc_unregister(void); /* internal */ -void *__ec_malloc(size_t size); -void __ec_free(void *ptr); -void *__ec_calloc(size_t nmemb, size_t size); -void *__ec_realloc(void *ptr, size_t size); -char *__ec_strdup(const char *s); -char *__ec_strndup(const char *s, size_t n); +void *__ec_malloc(size_t size, const char *file, unsigned int line); +void __ec_free(void *ptr, const char *file, unsigned int line); +void *__ec_calloc(size_t nmemb, size_t size, const char *file, + unsigned int line); +void *__ec_realloc(void *ptr, size_t size, const char *file, unsigned int line); +char *__ec_strdup(const char *s, const char *file, unsigned int line); +char *__ec_strndup(const char *s, size_t n, const char *file, + unsigned int line); /* we use macros here to ensure the file/line stay correct when * debugging the standard malloc with valgrind */ -#define ec_malloc(sz) ({ \ - void *ret_; \ - if (ec_malloc_handler.malloc == NULL) \ - ret_ = malloc(sz); \ - else \ - ret_ = __ec_malloc(sz); \ - ret_; \ +#define ec_malloc(sz) ({ \ + void *ret_; \ + if (ec_malloc_handler.malloc == NULL) \ + ret_ = malloc(sz); \ + else \ + ret_ = __ec_malloc(sz, __FILE__, __LINE__); \ + ret_; \ }) -#define ec_free(ptr) ({ \ - if (ec_malloc_handler.free == NULL) \ - free(ptr); \ - else \ - __ec_free(ptr); \ +#define ec_free(ptr) ({ \ + if (ec_malloc_handler.free == NULL) \ + free(ptr); \ + else \ + __ec_free(ptr, __FILE__, __LINE__); \ }) -#define ec_realloc(ptr, sz) ({ \ - void *ret_; \ - if (ec_malloc_handler.realloc == NULL) \ - ret_ = realloc(ptr, sz); \ - else \ - ret_ = __ec_realloc(ptr, sz); \ - ret_; \ +#define ec_realloc(ptr, sz) ({ \ + void *ret_; \ + if (ec_malloc_handler.realloc == NULL) \ + ret_ = realloc(ptr, sz); \ + else \ + ret_ = __ec_realloc(ptr, sz, __FILE__, __LINE__); \ + ret_; \ }) -#define ec_calloc(n, sz) ({ \ - void *ret_; \ - if (ec_malloc_handler.malloc == NULL) \ - ret_ = calloc(n, sz); \ - else \ - ret_ = __ec_calloc(n, sz); \ - ret_; \ +#define ec_calloc(n, sz) ({ \ + void *ret_; \ + if (ec_malloc_handler.malloc == NULL) \ + ret_ = calloc(n, sz); \ + else \ + ret_ = __ec_calloc(n, sz, __FILE__, __LINE__); \ + ret_; \ }) -#define ec_strdup(s) ({ \ - void *ret_; \ - if (ec_malloc_handler.malloc == NULL) \ - ret_ = strdup(s); \ - else \ - ret_ = __ec_strdup(s); \ - ret_; \ +#define ec_strdup(s) ({ \ + void *ret_; \ + if (ec_malloc_handler.malloc == NULL) \ + ret_ = strdup(s); \ + else \ + ret_ = __ec_strdup(s, __FILE__, __LINE__); \ + ret_; \ }) -#define ec_strndup(s, n) ({ \ - void *ret_; \ - if (ec_malloc_handler.malloc == NULL) \ - ret_ = strndup(s, n); \ - else \ - ret_ = __ec_strndup(s, n); \ - ret_; \ +#define ec_strndup(s, n) ({ \ + void *ret_; \ + if (ec_malloc_handler.malloc == NULL) \ + ret_ = strndup(s, n); \ + else \ + ret_ = __ec_strndup(s, n, __FILE__, __LINE__); \ + ret_; \ }) diff --git a/lib/ecoli_test.c b/lib/ecoli_test.c index 161c52c..e3942c6 100644 --- a/lib/ecoli_test.c +++ b/lib/ecoli_test.c @@ -29,6 +29,7 @@ #include #include +#include #include #include @@ -92,6 +93,140 @@ int ec_test_check_tk_complete(const struct ec_tk *tk, const char *input, return ret; } +TAILQ_HEAD(debug_alloc_hdr_list, debug_alloc_hdr); +static struct debug_alloc_hdr_list debug_alloc_hdr_list = + TAILQ_HEAD_INITIALIZER(debug_alloc_hdr_list); + +struct debug_alloc_hdr { + TAILQ_ENTRY(debug_alloc_hdr) next; + const char *file; + unsigned int line; + size_t size; + unsigned int cookie; +}; + +static void *debug_malloc(size_t size, const char *file, unsigned int line) +{ + struct debug_alloc_hdr *hdr; + size_t new_size = size + sizeof(*hdr) + sizeof(unsigned int); + void *ret; + + hdr = malloc(new_size); + if (hdr == NULL) { + ret = NULL; + } else { + hdr->file = file; + hdr->line = line; + hdr->size = size; + hdr->cookie = 0x12345678; + TAILQ_INSERT_TAIL(&debug_alloc_hdr_list, hdr, next); + ret = hdr + 1; + } + + printf("%s:%d: info: malloc(%zd) -> %p\n", file, line, size, ret); + + return ret; +} + +static void debug_free(void *ptr, const char *file, unsigned int line) +{ + struct debug_alloc_hdr *hdr, *h; + + (void)file; + (void)line; + + printf("%s:%d: info: free(%p)\n", file, line, ptr); + + if (ptr == NULL) + return; + + hdr = (ptr - sizeof(*hdr)); + if (hdr->cookie != 0x12345678) { + printf("%s:%d: error: free(%p): bad start cookie\n", + file, line, ptr); + abort(); + } + + TAILQ_FOREACH(h, &debug_alloc_hdr_list, next) { + if (h == hdr) + break; + } + + if (h == NULL) { + printf("%s:%d: error: free(%p): bad ptr\n", + file, line, ptr); + abort(); + } + + TAILQ_REMOVE(&debug_alloc_hdr_list, hdr, next); + free(hdr); +} + +void *debug_realloc(void *ptr, size_t size, const char *file, unsigned int line) +{ + struct debug_alloc_hdr *hdr = (ptr - sizeof(*hdr)); + struct debug_alloc_hdr *h; + size_t new_size = size + sizeof(*hdr) + sizeof(unsigned int); + void *ret; + + if (ptr != NULL) { + if (hdr->cookie != 0x12345678) { + printf("%s:%d: error: realloc(%p): bad start cookie\n", + file, line, ptr); + abort(); + } + + TAILQ_FOREACH(h, &debug_alloc_hdr_list, next) { + if (h == hdr) + break; + } + + if (h == NULL) { + printf("%s:%d: error: realloc(%p): bad ptr\n", + file, line, ptr); + abort(); + } + + TAILQ_REMOVE(&debug_alloc_hdr_list, h, next); + hdr = realloc(hdr, new_size); + if (hdr == NULL) { + TAILQ_INSERT_TAIL(&debug_alloc_hdr_list, h, next); + ret = NULL; + } else { + ret = hdr + 1; + } + } else { + hdr = realloc(NULL, new_size); + if (hdr == NULL) + ret = NULL; + else + ret= hdr + 1; + } + + if (hdr != NULL) { + hdr->file = file; + hdr->line = line; + hdr->size = size; + hdr->cookie = 0x12345678; + TAILQ_INSERT_TAIL(&debug_alloc_hdr_list, hdr, next); + } + + printf("%s:%d: info: realloc(%p, %zd) -> %p\n", + file, line, ptr, size, ret); + + return ret; +} + +void debug_alloc_dump(void) +{ + struct debug_alloc_hdr *hdr; + + TAILQ_FOREACH(hdr, &debug_alloc_hdr_list, next) { + printf("%s:%d: error: memory leak size=%zd ptr=%p\n", + hdr->file, hdr->line, hdr->size, hdr + 1); + } +} + /* int ec_test_check_tk_complete_list(const struct ec_tk *tk, */ /* const char *input, ...) */ @@ -100,7 +235,13 @@ int ec_test_all(void) struct ec_test *test; int ret = 0; - // XXX register a new malloc to trac memleaks + TAILQ_INIT(&debug_alloc_hdr_list); + + /* register a new malloc to trac memleaks */ + if (ec_malloc_register(debug_malloc, debug_free, debug_realloc) < 0) { + printf("cannot register new malloc\n"); + return -1; + } TAILQ_FOREACH(test, &test_list, next) { if (test->test() == 0) { @@ -111,5 +252,8 @@ int ec_test_all(void) } } + ec_malloc_unregister(); + debug_alloc_dump(); + return ret; } diff --git a/lib/ecoli_tk_int.c b/lib/ecoli_tk_int.c index bc6ee87..41ed54a 100644 --- a/lib/ecoli_tk_int.c +++ b/lib/ecoli_tk_int.c @@ -141,6 +141,7 @@ static int testcase(void) if (ec_tk_int_getval(tk, s) != 0) TEST_ERR(); } + ec_parsed_tk_free(p); p = ec_tk_parse(tk, "10"); s = ec_parsed_tk_to_string(p); @@ -150,7 +151,7 @@ static int testcase(void) if (ec_tk_int_getval(tk, s) != 10) TEST_ERR(); } - + ec_parsed_tk_free(p); ec_tk_free(tk); tk = ec_tk_int_new(NULL, -1, LLONG_MAX, 16); @@ -174,7 +175,7 @@ static int testcase(void) if (ec_tk_int_getval(tk, s) != 16) TEST_ERR(); } - + ec_parsed_tk_free(p); ec_tk_free(tk); tk = ec_tk_int_new(NULL, LLONG_MIN, 0, 10); diff --git a/lib/ecoli_tk_or.c b/lib/ecoli_tk_or.c index a81d669..9276c70 100644 --- a/lib/ecoli_tk_or.c +++ b/lib/ecoli_tk_or.c @@ -92,7 +92,10 @@ static struct ec_completed_tk *complete(const struct ec_tk *gen_tk, static void free_priv(struct ec_tk *gen_tk) { struct ec_tk_or *tk = (struct ec_tk_or *)gen_tk; + unsigned int i; + for (i = 0; i < tk->len; i++) + ec_tk_free(tk->table[i]); ec_free(tk->table); } @@ -108,16 +111,12 @@ struct ec_tk *ec_tk_or_new(const char *id) tk = (struct ec_tk_or *)ec_tk_new(id, &or_ops, sizeof(*tk)); if (tk == NULL) - goto fail; + return NULL; tk->table = NULL; tk->len = 0; return &tk->gen; - -fail: - ec_free(tk); - return NULL; } struct ec_tk *ec_tk_or_new_list(const char *id, ...) @@ -145,26 +144,26 @@ struct ec_tk *ec_tk_or_new_list(const char *id, ...) return &tk->gen; fail: - ec_free(tk); // XXX use tk_free? we need to delete all child on error + ec_tk_free(&tk->gen); /* will also free children */ va_end(ap); return NULL; } -int ec_tk_or_add(struct ec_tk *tk, struct ec_tk *child) +int ec_tk_or_add(struct ec_tk *gen_tk, struct ec_tk *child) { - struct ec_tk_or *or = (struct ec_tk_or *)tk; + struct ec_tk_or *tk = (struct ec_tk_or *)gen_tk; struct ec_tk **table; assert(tk != NULL); assert(child != NULL); - table = realloc(or->table, (or->len + 1) * sizeof(*or->table)); + table = ec_realloc(tk->table, (tk->len + 1) * sizeof(*tk->table)); if (table == NULL) return -1; - or->table = table; - table[or->len] = child; - or->len ++; + tk->table = table; + table[tk->len] = child; + tk->len ++; return 0; } diff --git a/lib/ecoli_tk_or.h b/lib/ecoli_tk_or.h index 130ec4d..a04c6a3 100644 --- a/lib/ecoli_tk_or.h +++ b/lib/ecoli_tk_or.h @@ -41,8 +41,10 @@ struct ec_tk_or { struct ec_tk *ec_tk_or_new(const char *id); /* list must be terminated with EC_TK_ENDLIST */ +/* all token given in the list will be freed when freeing this one */ struct ec_tk *ec_tk_or_new_list(const char *id, ...); +/* all token given in the list will be freed when freeing this one */ int ec_tk_or_add(struct ec_tk *tk, struct ec_tk *child); #endif diff --git a/lib/ecoli_tk_seq.c b/lib/ecoli_tk_seq.c index a1d3e68..4c182c4 100644 --- a/lib/ecoli_tk_seq.c +++ b/lib/ecoli_tk_seq.c @@ -37,20 +37,20 @@ // XXX to handle the quote, it will be done in tk_shseq // it will unquote the string and parse each token separately -static struct ec_parsed_tk *parse(const struct ec_tk *tk, +static struct ec_parsed_tk *parse(const struct ec_tk *gen_tk, const char *str) { - struct ec_tk_seq *seq = (struct ec_tk_seq *)tk; + struct ec_tk_seq *tk = (struct ec_tk_seq *)gen_tk; struct ec_parsed_tk *parsed_tk, *child_parsed_tk; size_t len = 0; unsigned int i; - parsed_tk = ec_parsed_tk_new(tk); + parsed_tk = ec_parsed_tk_new(gen_tk); if (parsed_tk == NULL) return NULL; - for (i = 0; i < seq->len; i++) { - child_parsed_tk = ec_tk_parse(seq->table[i], str + len); + for (i = 0; i < tk->len; i++) { + child_parsed_tk = ec_tk_parse(tk->table[i], str + len); if (child_parsed_tk == NULL) goto fail; @@ -67,8 +67,19 @@ static struct ec_parsed_tk *parse(const struct ec_tk *tk, return NULL; } +static void free_priv(struct ec_tk *gen_tk) +{ + struct ec_tk_seq *tk = (struct ec_tk_seq *)gen_tk; + unsigned int i; + + for (i = 0; i < tk->len; i++) + ec_tk_free(tk->table[i]); + ec_free(tk->table); +} + static struct ec_tk_ops seq_ops = { .parse = parse, + .free_priv = free_priv, }; struct ec_tk *ec_tk_seq_new(const char *id) @@ -77,16 +88,12 @@ struct ec_tk *ec_tk_seq_new(const char *id) tk = (struct ec_tk_seq *)ec_tk_new(id, &seq_ops, sizeof(*tk)); if (tk == NULL) - goto fail; + return NULL; tk->table = NULL; tk->len = 0; return &tk->gen; - -fail: - ec_free(tk); - return NULL; } struct ec_tk *ec_tk_seq_new_list(const char *id, ...) @@ -114,26 +121,26 @@ struct ec_tk *ec_tk_seq_new_list(const char *id, ...) return &tk->gen; fail: - ec_free(tk); // XXX use tk_free? we need to delete all child on error + ec_tk_free(&tk->gen); /* will also free children */ va_end(ap); return NULL; } -int ec_tk_seq_add(struct ec_tk *tk, struct ec_tk *child) +int ec_tk_seq_add(struct ec_tk *gen_tk, struct ec_tk *child) { - struct ec_tk_seq *seq = (struct ec_tk_seq *)tk; + struct ec_tk_seq *tk = (struct ec_tk_seq *)gen_tk; struct ec_tk **table; assert(tk != NULL); assert(child != NULL); - table = realloc(seq->table, seq->len + 1); + table = ec_realloc(tk->table, tk->len + 1); if (table == NULL) return -1; - seq->table = table; - table[seq->len] = child; - seq->len ++; + tk->table = table; + table[tk->len] = child; + tk->len ++; return 0; } -- 2.39.5