2 * Copyright (c) 2016, Olivier MATZ <zer0@droids-corp.org>
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
7 * * Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * * Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 * * Neither the name of the University of California, Berkeley nor the
13 * names of its contributors may be used to endorse or promote products
14 * derived from this software without specific prior written permission.
16 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
17 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
20 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 #include <ecoli_malloc.h>
33 #include <ecoli_test.h>
36 static struct ec_test_list test_list = TAILQ_HEAD_INITIALIZER(test_list);
38 /* register a driver */
39 void ec_test_register(struct ec_test *test)
41 TAILQ_INSERT_TAIL(&test_list, test, next);
44 int ec_test_check_tk_parse(const struct ec_tk *tk, const char *input,
47 struct ec_parsed_tk *p;
51 p = ec_tk_parse(tk, input);
52 s = ec_parsed_tk_to_string(p);
53 if (s == NULL && expected == NULL)
55 else if (s != NULL && expected != NULL &&
59 if (expected == NULL && ret != 0)
60 printf("tk should not match but matches <%s>\n", s);
61 if (expected != NULL && ret != 0)
62 printf("tk should match <%s> but matches <%s>\n",
70 int ec_test_check_tk_complete(const struct ec_tk *tk, const char *input,
73 struct ec_completed_tk *p;
77 p = ec_tk_complete(tk, input);
78 s = ec_completed_tk_smallest_start(p);
79 if (s == NULL && expected == NULL)
81 else if (s != NULL && expected != NULL &&
85 if (expected == NULL && ret != 0)
86 printf("tk should not complete but completes with <%s>\n", s);
87 if (expected != NULL && ret != 0)
88 printf("tk should complete with <%s> but completes with <%s>\n",
91 ec_completed_tk_free(p);
96 TAILQ_HEAD(debug_alloc_hdr_list, debug_alloc_hdr);
97 static struct debug_alloc_hdr_list debug_alloc_hdr_list =
98 TAILQ_HEAD_INITIALIZER(debug_alloc_hdr_list);
100 struct debug_alloc_hdr {
101 TAILQ_ENTRY(debug_alloc_hdr) next;
108 static void *debug_malloc(size_t size, const char *file, unsigned int line)
110 struct debug_alloc_hdr *hdr;
111 size_t new_size = size + sizeof(*hdr) + sizeof(unsigned int);
114 hdr = malloc(new_size);
121 hdr->cookie = 0x12345678;
122 TAILQ_INSERT_TAIL(&debug_alloc_hdr_list, hdr, next);
126 printf("%s:%d: info: malloc(%zd) -> %p\n", file, line, size, ret);
131 static void debug_free(void *ptr, const char *file, unsigned int line)
133 struct debug_alloc_hdr *hdr, *h;
138 printf("%s:%d: info: free(%p)\n", file, line, ptr);
143 hdr = (ptr - sizeof(*hdr));
144 if (hdr->cookie != 0x12345678) {
145 printf("%s:%d: error: free(%p): bad start cookie\n",
150 TAILQ_FOREACH(h, &debug_alloc_hdr_list, next) {
156 printf("%s:%d: error: free(%p): bad ptr\n",
161 TAILQ_REMOVE(&debug_alloc_hdr_list, hdr, next);
165 void *debug_realloc(void *ptr, size_t size, const char *file, unsigned int line)
167 struct debug_alloc_hdr *hdr = (ptr - sizeof(*hdr));
168 struct debug_alloc_hdr *h;
169 size_t new_size = size + sizeof(*hdr) + sizeof(unsigned int);
173 if (hdr->cookie != 0x12345678) {
174 printf("%s:%d: error: realloc(%p): bad start cookie\n",
179 TAILQ_FOREACH(h, &debug_alloc_hdr_list, next) {
185 printf("%s:%d: error: realloc(%p): bad ptr\n",
190 TAILQ_REMOVE(&debug_alloc_hdr_list, h, next);
191 hdr = realloc(hdr, new_size);
193 TAILQ_INSERT_TAIL(&debug_alloc_hdr_list, h, next);
199 hdr = realloc(NULL, new_size);
210 hdr->cookie = 0x12345678;
211 TAILQ_INSERT_TAIL(&debug_alloc_hdr_list, hdr, next);
214 printf("%s:%d: info: realloc(%p, %zd) -> %p\n",
215 file, line, ptr, size, ret);
220 void debug_alloc_dump(void)
222 struct debug_alloc_hdr *hdr;
224 TAILQ_FOREACH(hdr, &debug_alloc_hdr_list, next) {
225 printf("%s:%d: error: memory leak size=%zd ptr=%p\n",
226 hdr->file, hdr->line, hdr->size, hdr + 1);
230 /* int ec_test_check_tk_complete_list(const struct ec_tk *tk, */
231 /* const char *input, ...) */
233 int ec_test_all(void)
235 struct ec_test *test;
238 TAILQ_INIT(&debug_alloc_hdr_list);
240 /* register a new malloc to trac memleaks */
241 if (ec_malloc_register(debug_malloc, debug_free, debug_realloc) < 0) {
242 printf("cannot register new malloc\n");
246 TAILQ_FOREACH(test, &test_list, next) {
247 if (test->test() == 0) {
248 printf("== test %-20s success\n", test->name);
250 printf("== test %-20s failed\n", test->name);
255 ec_malloc_unregister();