From bf0579a44a448eebfdd4af1c6f309221b8662633 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Sat, 20 Nov 2021 13:59:22 -0800 Subject: [PATCH] drd: Add a test program that interrupts pthread_mutex_lock() This test fails, probably due to differences between native signal handling and signal handling in the Valgrind core. --- drd/tests/Makefile.am | 3 + drd/tests/pth_mutex_signal.c | 95 +++++++++++++++++++++++++++ drd/tests/pth_mutex_signal.stderr.exp | 15 +++++ drd/tests/pth_mutex_signal.vgtest | 3 + 4 files changed, 116 insertions(+) create mode 100644 drd/tests/pth_mutex_signal.c create mode 100644 drd/tests/pth_mutex_signal.stderr.exp create mode 100644 drd/tests/pth_mutex_signal.vgtest diff --git a/drd/tests/Makefile.am b/drd/tests/Makefile.am index c804391e81..ac487def3c 100755 --- a/drd/tests/Makefile.am +++ b/drd/tests/Makefile.am @@ -227,6 +227,8 @@ EXTRA_DIST = \ pth_inconsistent_cond_wait.vgtest \ pth_mutex_reinit.stderr.exp \ pth_mutex_reinit.vgtest \ + pth_mutex_signal.stderr.exp \ + pth_mutex_signal.vgtest \ pth_once.stderr.exp \ pth_once.vgtest \ pth_process_shared_mutex.stderr.exp \ @@ -410,6 +412,7 @@ check_PROGRAMS = \ pth_detached3 \ pth_inconsistent_cond_wait \ pth_mutex_reinit \ + pth_mutex_signal \ pth_process_shared_mutex \ recursive_mutex \ rwlock_race \ diff --git a/drd/tests/pth_mutex_signal.c b/drd/tests/pth_mutex_signal.c new file mode 100644 index 0000000000..ec74696953 --- /dev/null +++ b/drd/tests/pth_mutex_signal.c @@ -0,0 +1,95 @@ +/* + * See also https://bugs.kde.org/show_bug.cgi?id=445743. + */ + +#include +#include +#include +#include +#include +#include +#include + +#define STACK_SIZE 1024 * 512 +#define NATIVE_IO_INTERRUPT_SIGNAL (SIGRTMAX - 2) +#define LONG_SLEEP_TIME 1000000 + +void *contender_start(void *arg) +{ + pthread_mutex_t *mutex = arg; + int ret; + + ret = pthread_mutex_lock(mutex); + assert(ret == 0); + fprintf(stderr, "contender locked mutex\n"); + fprintf(stderr, "contender unlocking mutex\n"); + pthread_mutex_unlock(mutex); + fprintf(stderr, "contender unlocked mutex\n"); + return NULL; +} + +void nullHandler(int signal, siginfo_t *info, void *context) +{ + static const char *msg = "nullHandler running\n"; + + write(STDERR_FILENO, msg, strlen(msg)); +} + +int main () +{ + pthread_mutex_t mutex; + pthread_mutexattr_t mutex_attr; + pthread_attr_t thread_attr_contender; + pthread_t contender; + struct sigaction signalAction = { }; + + // install signal handler + signalAction.sa_sigaction = nullHandler; + sigfillset(&signalAction.sa_mask); + signalAction.sa_flags = 0; + sigaction(NATIVE_IO_INTERRUPT_SIGNAL, &signalAction, NULL); + + // initialize the mutex + pthread_mutexattr_init(&mutex_attr); + pthread_mutexattr_setprotocol(&mutex_attr, PTHREAD_PRIO_INHERIT); + pthread_mutex_init(&mutex, &mutex_attr); + fprintf(stderr, "mutex initialized\n"); + + // lock mutex + pthread_mutex_lock(&mutex); + + // init and create contender + pthread_attr_init(&thread_attr_contender); + pthread_attr_setstacksize(&thread_attr_contender, STACK_SIZE); + pthread_attr_setinheritsched(&thread_attr_contender, PTHREAD_EXPLICIT_SCHED); + fprintf(stderr, "thread attributes initialized\n"); + if (pthread_create(&contender, &thread_attr_contender, &contender_start, + &mutex) != 0) { + fprintf(stderr, "failed to create thread\n"); + return 1; + } + fprintf(stderr, "thread created\n"); + pthread_attr_destroy(&thread_attr_contender); + + // wait until the thread is sleeping inside pthread_mutex_lock(). + fprintf(stderr, "sleeping\n"); + usleep(LONG_SLEEP_TIME); + + // signal thread + fprintf(stderr, "signalling\n"); + pthread_kill(contender, NATIVE_IO_INTERRUPT_SIGNAL); + + fprintf(stderr, "sleeping\n"); + usleep(LONG_SLEEP_TIME); + + fprintf(stderr, "unlocking\n"); + pthread_mutex_unlock(&mutex); + + usleep(LONG_SLEEP_TIME); + + // finally wait for the thread + fprintf(stderr, "joining thread\n"); + pthread_join(contender, NULL); + + return 0; +} diff --git a/drd/tests/pth_mutex_signal.stderr.exp b/drd/tests/pth_mutex_signal.stderr.exp new file mode 100644 index 0000000000..63f38b08cf --- /dev/null +++ b/drd/tests/pth_mutex_signal.stderr.exp @@ -0,0 +1,15 @@ + +mutex initialized +thread attributes initialized +thread created +sleeping +signalling +sleeping +nullHandler running +unlocking +contender locked mutex +contender unlocking mutex +contender unlocked mutex +joining thread + +ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) diff --git a/drd/tests/pth_mutex_signal.vgtest b/drd/tests/pth_mutex_signal.vgtest new file mode 100644 index 0000000000..aaf967bb4a --- /dev/null +++ b/drd/tests/pth_mutex_signal.vgtest @@ -0,0 +1,3 @@ +prereq: ./supported_libpthread && [ -e pth_mutex_signal ] +vgopts: --check-stack-var=yes --read-var-info=yes +prog: pth_mutex_signal -- 2.47.2