]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
drd: Add a test program that interrupts pthread_mutex_lock()
authorBart Van Assche <bvanassche@acm.org>
Sat, 20 Nov 2021 21:59:22 +0000 (13:59 -0800)
committerBart Van Assche <bvanassche@acm.org>
Sat, 20 Nov 2021 22:28:05 +0000 (14:28 -0800)
This test fails, probably due to differences between native signal handling
and signal handling in the Valgrind core.

drd/tests/Makefile.am
drd/tests/pth_mutex_signal.c [new file with mode: 0644]
drd/tests/pth_mutex_signal.stderr.exp [new file with mode: 0644]
drd/tests/pth_mutex_signal.vgtest [new file with mode: 0644]

index c804391e81c79209ba2e219bbc58dd22a5827eb3..ac487def3c328a4c9c8d327b703e596edc809d8d 100755 (executable)
@@ -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 (file)
index 0000000..ec74696
--- /dev/null
@@ -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;
+}
diff --git a/drd/tests/pth_mutex_signal.stderr.exp b/drd/tests/pth_mutex_signal.stderr.exp
new file mode 100644 (file)
index 0000000..63f38b0
--- /dev/null
@@ -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 (file)
index 0000000..aaf967b
--- /dev/null
@@ -0,0 +1,3 @@
+prereq: ./supported_libpthread && [ -e pth_mutex_signal ]
+vgopts: --check-stack-var=yes --read-var-info=yes
+prog: pth_mutex_signal