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.
This commit is contained in:
Bart Van Assche 2021-11-20 13:59:22 -08:00
parent 8ad4c01880
commit bf0579a44a
4 changed files with 116 additions and 0 deletions

View File

@ -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 \

View File

@ -0,0 +1,95 @@
/*
* See also https://bugs.kde.org/show_bug.cgi?id=445743.
*/
#include <assert.h>
#include <pthread.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#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;
}

View File

@ -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)

View File

@ -0,0 +1,3 @@
prereq: ./supported_libpthread && [ -e pth_mutex_signal ]
vgopts: --check-stack-var=yes --read-var-info=yes
prog: pth_mutex_signal