aboutsummaryrefslogtreecommitdiffstats
path: root/libtest/libtest_check_no_leaks.c
diff options
context:
space:
mode:
Diffstat (limited to 'libtest/libtest_check_no_leaks.c')
-rw-r--r--libtest/libtest_check_no_leaks.c77
1 files changed, 77 insertions, 0 deletions
diff --git a/libtest/libtest_check_no_leaks.c b/libtest/libtest_check_no_leaks.c
new file mode 100644
index 0000000..15f7e58
--- /dev/null
+++ b/libtest/libtest_check_no_leaks.c
@@ -0,0 +1,77 @@
+/* See LICENSE file for copyright and license details. */
+#include "common.h"
+extern int libtest_suppress_leak_output;
+#ifndef TEST
+
+
+int libtest_suppress_leak_output = 0;
+
+
+static int
+check_no_memory_leaks(void)
+{
+ struct meminfo *mem;
+ int no_leaks = 1;
+
+ SPINLOCK(libtest_allocs_list_spinlock);
+
+ if (!libtest_allocs_list_inited)
+ goto out;
+
+ libtest_kill_malloc_tracking++;
+ libtest_malloc_internal_usage++;
+ for (mem = libtest_allocs_head.next; mem->next; mem = mem->next) {
+ if (mem->accept_leakage)
+ continue;
+ no_leaks = 0;
+ if (libtest_suppress_leak_output)
+ continue;
+ fprintf(stderr, "Memory leak: %p (alloc-size=%zu)\n",
+ mem->usable_area, mem->requested_alloc_size);
+#ifdef WITH_BACKTRACE
+ if (mem->backtrace)
+ libtest_print_backtrace(stderr, "\tat ", 0u, mem->backtrace);
+#endif
+ fflush(stderr);
+ }
+ libtest_malloc_internal_usage--;
+ libtest_kill_malloc_tracking--;
+
+out:
+ SPINUNLOCK(libtest_allocs_list_spinlock);
+ return no_leaks;
+}
+
+
+int
+libtest_check_no_leaks(void)
+{
+ /* TODO check file descriptor leaks */
+ return check_no_memory_leaks();
+}
+
+
+#else
+
+
+int
+main(void)
+{
+ void *p;
+
+ SET_UP_ALARM();
+
+ libtest_start_tracking();
+ assert(p = malloc(1u));
+ libtest_suppress_leak_output = 1;
+ EXPECT(!libtest_check_no_leaks());
+ libtest_suppress_leak_output = 0;
+ free(p);
+ libtest_stop_tracking();
+ EXPECT(libtest_check_no_leaks());
+
+ return 0;
+}
+
+
+#endif