Add test reproducing ASAN-like hangs

Backtraces suggest that AddressSanitizer replaces malloc() with a
function that

- locks a mutex and
- calls clock_gettime() while the mutex is held

This commit adds a test that implements a trivial malloc() that behaves
similarly. Currently, this test hangs.

Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
Uli Schlachter
2022-05-04 14:25:13 +02:00
parent f836ea3eb3
commit 6e0f978079
3 changed files with 92 additions and 1 deletions

View File

@@ -26,7 +26,7 @@ all: $(ALL_TESTS)
timetest: ${OBJ}
${CC} -o $@ ${OBJ} ${LDFLAGS}
test: timetest functest
test: timetest functest libmallocintercept.so
@echo
@./test.sh
@@ -40,6 +40,9 @@ functest:
randomtest: repeat_random
./randomtest.sh
libmallocintercept.so: libmallocintercept.c
${CC} -shared -o $@ -fpic ${CFLAGS} $<
# ensure our variadic argument unpacking/repacking works as expected
confirm_variadic_promotion: variadic_promotion
./variadic_promotion

79
test/libmallocintercept.c Normal file
View File

@@ -0,0 +1,79 @@
/*
* Copyright (C) 2022 be.storaged GmbH
*
* This file is part of libfaketime
*
* libfaketime is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License v2 as published by the
* Free Software Foundation.
*
* libfaketime is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License v2 along
* with the libfaketime; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <unistd.h>
static void print_msg(const char *msg) {
write(0, msg, strlen(msg));
}
static void* actual_malloc(size_t size) {
/* We would like to use "the real malloc", but cannot. Thus, this
* implements a trivial, allocate-only bump allocator to make things
* work.
*/
static char memory_arena[16 << 20];
static size_t allocated_index = 0;
void *result = &memory_arena[allocated_index];
allocated_index += size;
/* align to a multiple of 8 bytes */
allocated_index = (allocated_index + 7) / 8 * 8;
if (allocated_index >= sizeof(memory_arena)) {
print_msg("libmallocintercept is out of memory!");
abort();
}
return result;
}
static void poke_faketime(void) {
/* To complicate things for libfaketime, this calls clock_gettime()
* while holding a lock. This should simulate problems that occurred
* with address sanitizer.
*/
static pthread_mutex_t time_mutex = PTHREAD_MUTEX_INITIALIZER;
struct timespec timespec;
pthread_mutex_lock(&time_mutex);
clock_gettime(CLOCK_REALTIME, &timespec);
pthread_mutex_unlock(&time_mutex);
}
void *malloc(size_t size) {
print_msg("Called malloc() from libmallocintercept...");
poke_faketime();
print_msg("successfully\n");
return actual_malloc(size);
}
void free(void *) {
print_msg("Called free() from libmallocintercept...");
poke_faketime();
print_msg("successfully\n");
/* We cannot actually free memory */
}

View File

@@ -1,6 +1,7 @@
#!/bin/sh
FTPL="${FAKETIME_TESTLIB:-../src/libfaketime.so.1}"
MALLOC_INTERCEPT=./libmallocintercept.so
if [ -f /etc/faketimerc ] ; then
echo "Running the test program with your system-wide default in /etc/faketimerc"
@@ -62,6 +63,14 @@ echo "\$ LD_PRELOAD=$FTPL FAKETIME=\"-15d\" date"
LD_PRELOAD="$FTPL" FAKETIME="-15d" date
echo
echo "============================================================================="
echo
echo "Running the test program with malloc interception"
echo "\$ LD_PRELOAD=./libmallocintercept.so:$FTPL ./timetest"
LD_PRELOAD="./libmallocintercept.so:$FTPL" ./timetest
echo
echo "============================================================================="
echo "Testing finished."