aboutsummaryrefslogtreecommitdiffstats
path: root/libtest
diff options
context:
space:
mode:
authorMattias Andrée <m@maandree.se>2026-05-14 15:55:33 +0200
committerMattias Andrée <m@maandree.se>2026-05-14 15:55:33 +0200
commit4e6f25806e3c9fa4753ce959ef990167796acd32 (patch)
treee641de9953f5b58afc1f36efe9c42a0d20254cd2 /libtest
parentFix libtest and add file descriptor leak detection (diff)
downloadlibrecrypt-4e6f25806e3c9fa4753ce959ef990167796acd32.tar.gz
librecrypt-4e6f25806e3c9fa4753ce959ef990167796acd32.tar.bz2
librecrypt-4e6f25806e3c9fa4753ce959ef990167796acd32.tar.xz
Tests and fixes
Signed-off-by: Mattias Andrée <m@maandree.se>
Diffstat (limited to 'libtest')
-rw-r--r--libtest/common.h6
-rw-r--r--libtest/globals.c6
-rw-r--r--libtest/libtest.h13
-rw-r--r--libtest/libtest_fd_tracking.c11
-rw-r--r--libtest/libtest_free.c10
-rw-r--r--libtest/libtest_print_backtrace.c6
6 files changed, 46 insertions, 6 deletions
diff --git a/libtest/common.h b/libtest/common.h
index 54456d2..e4344a9 100644
--- a/libtest/common.h
+++ b/libtest/common.h
@@ -157,9 +157,9 @@ extern struct meminfo libtest_allocs_tail;
extern int libtest_allocs_list_inited;
extern atomic_flag libtest_allocs_list_spinlock;
-extern int libtest_zero_on_alloc;
-extern int libtest_expect_zeroed;
-extern int libtest_malloc_accept_leakage;
+extern _Thread_local int libtest_zero_on_alloc;
+extern _Thread_local int libtest_expect_zeroed;
+extern _Thread_local int libtest_malloc_accept_leakage;
extern _Thread_local size_t libtest_malloc_internal_usage;
extern _Thread_local size_t libtest_kill_malloc_tracking;
diff --git a/libtest/globals.c b/libtest/globals.c
index cf8164e..e5229a1 100644
--- a/libtest/globals.c
+++ b/libtest/globals.c
@@ -30,9 +30,9 @@ struct meminfo libtest_allocs_tail;
int libtest_allocs_list_inited = 0;
atomic_flag libtest_allocs_list_spinlock = ATOMIC_FLAG_INIT;
-int libtest_zero_on_alloc = 0;
-int libtest_expect_zeroed = 0;
-int libtest_malloc_accept_leakage = 1;
+_Thread_local int libtest_zero_on_alloc = 0;
+_Thread_local int libtest_expect_zeroed = 0;
+_Thread_local int libtest_malloc_accept_leakage = 1;
_Thread_local size_t libtest_malloc_internal_usage = 0u;
_Thread_local size_t libtest_kill_malloc_tracking = 0u;
diff --git a/libtest/libtest.h b/libtest/libtest.h
index 8f44114..e4b4098 100644
--- a/libtest/libtest.h
+++ b/libtest/libtest.h
@@ -7,18 +7,27 @@
/**
* Start tracking resources which `libtest_check_no_leaks`
* will detect if they are not released
+ *
+ * Memory resource tracking will only be started for the
+ * calling thread
*/
void libtest_start_tracking(void);
/**
* Stop tracking resources, so that `libtest_check_no_leaks`
* will not detect if they are not released
+ *
+ * Memory resource tracking will only be stop for the
+ * calling thread
*/
void libtest_stop_tracking(void);
/**
* Check for resource leaks
*
+ * Memory leaks are detected for all threads with
+ * tracking enabled, not just the calling thread
+ *
* Any leak will be printed to standard error
*
* @return 1 if there was no leaks, 0 otherwise
@@ -30,6 +39,8 @@ int libtest_check_no_leaks(void);
* Make all overriden memory allocation functions
* full the usable memory area with null bytes,
* or disable this feature
+ *
+ * The setting applies only to the calling thread
*
* @param enabled 1 to enable, 0 to disable
*/
@@ -40,6 +51,8 @@ void libtest_force_zero_on_alloc(int enabled);
* check that the entire usable memory area is filled
* with null bytes, or disable this feature
*
+ * The setting applies only to the calling thread
+ *
* @param enabled 1 to enable, 0 to disable
*/
void libtest_expect_zeroed_on_free(int enabled);
diff --git a/libtest/libtest_fd_tracking.c b/libtest/libtest_fd_tracking.c
index d3c766c..25cea8f 100644
--- a/libtest/libtest_fd_tracking.c
+++ b/libtest/libtest_fd_tracking.c
@@ -11,6 +11,9 @@ struct fd {
static size_t nopened = 0u;
static struct fd *opened = NULL;
+static atomic_flag spinlock = ATOMIC_FLAG_INIT;
+static int tracking_state = -1;
+
static int
cmp_fd(const void *av, const void *bv)
@@ -60,6 +63,14 @@ libtest_fd_tracking(int action)
int accept_memleak = libtest_malloc_accept_leakage;
size_t i, j;
char *path;
+ int old_tracking_state;
+
+ SPINLOCK(spinlock);
+ old_tracking_state = tracking_state;
+ tracking_state = action;
+ SPINUNLOCK(spinlock);
+ if (old_tracking_state == action)
+ return 1;
/* so libtest doesn't complain about us not zeroing before freeing,
* and so it will not report memory leaks in fprintf from our
diff --git a/libtest/libtest_free.c b/libtest/libtest_free.c
index 3e84ba6..bdc214b 100644
--- a/libtest/libtest_free.c
+++ b/libtest/libtest_free.c
@@ -57,6 +57,16 @@ libtest_free(void *ptr, enum libtest_zero_check zero_checking)
break;
}
}
+ if (!memory_zeroed && mem->backtrace) {
+ libtest_malloc_internal_usage++;
+ inside_free = 1;
+ fprintf(stderr, "Memory not zeroed out before deallocation: %p\n", ptr);
+#ifdef WITH_BACKTRACE
+ libtest_print_backtrace(stderr, "\tAllocated at ", "\t at ",
+ 0u, mem->backtrace, NULL);
+#endif
+ inside_free = 0;
+ }
assert(memory_zeroed);
}
diff --git a/libtest/libtest_print_backtrace.c b/libtest/libtest_print_backtrace.c
index e595131..7bc465c 100644
--- a/libtest/libtest_print_backtrace.c
+++ b/libtest/libtest_print_backtrace.c
@@ -19,6 +19,7 @@ libtest_print_backtrace(FILE *fp, const char *prefix, const char *indent, size_t
unw_context_t context;
Dwarf_Addr ip;
size_t i;
+ unsigned int old_alarm;
#if defined(HAVE_LINE_INFO)
Dwfl_Callbacks callbacks;
char *debuginfo_path = NULL;
@@ -32,6 +33,9 @@ libtest_print_backtrace(FILE *fp, const char *prefix, const char *indent, size_t
if (recursion_guard)
return;
+
+ old_alarm = alarm(1u);
+
saved_errno = errno;
recursion_guard = 1;
libtest_malloc_internal_usage++;
@@ -121,6 +125,8 @@ out:
libtest_malloc_internal_usage--;
recursion_guard = 0;
errno = saved_errno;
+
+ alarm(old_alarm);
}