From: Jan Kiszka <jan.kiszka@domain.hid>
To: xenomai-core <xenomai@xenomai.org>
Subject: [Xenomai-core] [PATCH] Add sigdebug unit test
Date: Wed, 25 Jan 2012 17:21:37 +0100 [thread overview]
Message-ID: <4F202C11.70908@domain.hid> (raw)
We had two regressions in this code recently. So test all 6 possible
SIGDEBUG reasons, or 5 if the watchdog is not available.
Signed-off-by: Jan Kiszka <jan.kiszka@domain.hid>
---
src/testsuite/unit/Makefile.am | 16 +++-
src/testsuite/unit/sigdebug.c | 233 ++++++++++++++++++++++++++++++++++++++++
2 files changed, 248 insertions(+), 1 deletions(-)
create mode 100644 src/testsuite/unit/sigdebug.c
diff --git a/src/testsuite/unit/Makefile.am b/src/testsuite/unit/Makefile.am
index 1bf5d8d..6e8203d 100644
--- a/src/testsuite/unit/Makefile.am
+++ b/src/testsuite/unit/Makefile.am
@@ -11,7 +11,8 @@ test_PROGRAMS = \
cond-torture-posix \
cond-torture-native \
check-vdso \
- rtdm
+ rtdm \
+ sigdebug
arith_SOURCES = arith.c arith-noinline.c arith-noinline.h
@@ -119,3 +120,16 @@ rtdm_LDADD = \
../../skins/native/libnative.la \
../../skins/common/libxenomai.la \
-lpthread -lrt -lm
+
+sigdebug_SOURCES = sigdebug.c
+
+sigdebug_CPPFLAGS = \
+ @XENO_USER_CFLAGS@ \
+ -I$(top_srcdir)/include
+
+sigdebug_LDFLAGS = @XENO_USER_LDFLAGS@
+
+sigdebug_LDADD = \
+ ../../skins/native/libnative.la \
+ ../../skins/common/libxenomai.la \
+ -lpthread -lm
diff --git a/src/testsuite/unit/sigdebug.c b/src/testsuite/unit/sigdebug.c
new file mode 100644
index 0000000..57d9beb
--- /dev/null
+++ b/src/testsuite/unit/sigdebug.c
@@ -0,0 +1,233 @@
+/*
+ * Functional testing of unwanted domain switch debugging mechanism.
+ *
+ * Copyright (C) Jan Kiszka <jan.kiszka@domain.hid>
+ *
+ * Released under the terms of GPLv2.
+ */
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <stdbool.h>
+#include <string.h>
+#include <signal.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <pthread.h>
+#include <rtdk.h>
+#include <native/task.h>
+#include <native/mutex.h>
+#include <native/sem.h>
+#include <native/timer.h>
+
+#define WRITE_TEST_SIZE (4*1024)
+
+unsigned int expected_reason;
+bool sigdebug_received;
+pthread_t rt_task_thread;
+RT_MUTEX prio_invert;
+RT_SEM send_signal;
+char *mem;
+FILE *wd;
+
+static void setup_checkdebug(unsigned int reason)
+{
+ sigdebug_received = false;
+ expected_reason = reason;
+}
+
+static void check_inner(const char *fn, int line, const char *msg,
+ int status, int expected)
+{
+ if (status == expected)
+ return;
+
+ rt_task_set_mode(T_WARNSW, 0, NULL);
+ rt_print_flush_buffers();
+ fprintf(stderr, "FAILURE %s:%d: %s returned %d instead of %d - %s\n",
+ fn, line, msg, status, expected, strerror(-status));
+ exit(EXIT_FAILURE);
+}
+
+static void check_sigdebug_inner(const char *fn, int line, const char *reason)
+{
+ if (sigdebug_received)
+ return;
+
+ rt_task_set_mode(T_WARNSW, 0, NULL);
+ rt_print_flush_buffers();
+ fprintf(stderr, "FAILURE %s:%d: no %s received\n", fn, line, reason);
+ exit(EXIT_FAILURE);
+}
+
+#define check(msg, status, expected) ({ \
+ int __status = status; \
+ check_inner(__FUNCTION__, __LINE__, msg, __status, expected); \
+ __status; \
+})
+
+#define check_no_error(msg, status) ({ \
+ int __status = status; \
+ check_inner(__FUNCTION__, __LINE__, msg, \
+ __status < 0 ? __status : 0, 0); \
+ __status; \
+})
+
+#define check_sigdebug_received(reason) do { \
+ const char *__reason = reason; \
+ check_sigdebug_inner(__FUNCTION__, __LINE__, __reason); \
+} while (0)
+
+void rt_task_body(void *cookie)
+{
+ RTIME end;
+ int err;
+
+ rt_task_thread = pthread_self();
+
+ rt_printf("syscall\n");
+ setup_checkdebug(SIGDEBUG_MIGRATE_SYSCALL);
+ syscall(-1);
+ check_sigdebug_received("SIGDEBUG_MIGRATE_SYSCALL");
+
+ rt_printf("signal\n");
+ setup_checkdebug(SIGDEBUG_MIGRATE_SIGNAL);
+ err = rt_sem_v(&send_signal);
+ check_no_error("rt_sem_v", err);
+ rt_task_sleep(10000000LL);
+ check_sigdebug_received("SIGDEBUG_MIGRATE_SIGNAL");
+
+ rt_printf("relaxed mutex owner\n");
+ setup_checkdebug(SIGDEBUG_MIGRATE_PRIOINV);
+ err = rt_mutex_acquire(&prio_invert, TM_INFINITE);
+ check("rt_mutex_acquire", err, -EINTR);
+ check_sigdebug_received("SIGDEBUG_MIGRATE_PRIOINV");
+
+
+ rt_printf("page fault\n");
+ setup_checkdebug(SIGDEBUG_MIGRATE_FAULT);
+ rt_task_sleep(0);
+ *mem ^= 0xFF;
+ check_sigdebug_received("SIGDEBUG_MIGRATE_FAULT");
+
+ if (wd) {
+ rt_printf("watchdog\n");
+ rt_print_flush_buffers();
+ setup_checkdebug(SIGDEBUG_WATCHDOG);
+ end = rt_timer_tsc() + rt_timer_ns2tsc(2100000000ULL);
+ rt_task_sleep(0);
+ while (rt_timer_tsc() < end && !sigdebug_received)
+ /* busy loop */;
+ check_sigdebug_received("SIGDEBUG_WATCHDOG");
+ } else
+ rt_printf("note: watchdog not available\n");
+}
+
+void sigdebug_handler(int sig, siginfo_t *si, void *context)
+{
+ unsigned int reason = si->si_value.sival_int;
+
+ if (reason != expected_reason) {
+ rt_print_flush_buffers();
+ fprintf(stderr, "FAILURE: sigdebug_handler expected reason %d,"
+ " received %d\n", expected_reason, reason);
+ exit(EXIT_FAILURE);
+ }
+ sigdebug_received = true;
+}
+
+void dummy_handler(int sig, siginfo_t *si, void *context)
+{
+}
+
+int main(int argc, char **argv)
+{
+ char tempname[] = "/tmp/sigdebug-XXXXXX";
+ RT_TASK main_task, rt_task;
+ struct sigaction sa;
+ int old_wd_value;
+ int tmp_fd;
+ int err;
+
+ rt_print_auto_init(1);
+
+ wd = fopen("/sys/module/xeno_nucleus/parameters/watchdog_timeout",
+ "w+");
+ if (wd) {
+ err = fscanf(wd, "%d", &old_wd_value);
+ check("get watchdog", err, 1);
+ err = fprintf(wd, "2");
+ check("set watchdog", err, 1);
+ fflush(wd);
+ }
+
+ sigemptyset(&sa.sa_mask);
+ sa.sa_sigaction = sigdebug_handler;
+ sa.sa_flags = SA_SIGINFO;
+ sigaction(SIGDEBUG, &sa, NULL);
+
+ sa.sa_sigaction = dummy_handler;
+ sigaction(SIGUSR1, &sa, NULL);
+
+ printf("mlockall\n");
+ setup_checkdebug(SIGDEBUG_NOMLOCK);
+ err = rt_task_shadow(&main_task, "main_task", 0, 0);
+ check("rt_task_shadow", err, -EINTR);
+ check_sigdebug_received("SIGDEBUG_NOMLOCK");
+
+ mlockall(MCL_CURRENT | MCL_FUTURE);
+
+ errno = 0;
+ tmp_fd = mkstemp(tempname);
+ check_no_error("mkstemp", -errno);
+ unlink(tempname);
+ check_no_error("unlink", -errno);
+ mem = mmap(NULL, 1, PROT_READ | PROT_WRITE, MAP_SHARED, tmp_fd, 0);
+ check_no_error("mmap", -errno);
+ err = write(tmp_fd, "X", 1);
+ check("write", err, 1);
+
+ err = rt_task_shadow(&main_task, "main_task", 0, 0);
+ check_no_error("rt_task_shadow", err);
+
+ err = rt_mutex_create(&prio_invert, "prio_invert");
+ check_no_error("rt_mutex_create", err);
+
+ err = rt_mutex_acquire(&prio_invert, TM_INFINITE);
+ check_no_error("rt_mutex_acquire", err);
+
+ err = rt_sem_create(&send_signal, "send_signal", 0, S_PRIO);
+ check_no_error("rt_sem_create", err);
+
+ err = rt_task_spawn(&rt_task, "rt_task", 0, 1, T_WARNSW | T_JOINABLE,
+ rt_task_body, NULL);
+ check_no_error("rt_task_spawn", err);
+
+ err = rt_sem_p(&send_signal, TM_INFINITE);
+ check_no_error("rt_sem_signal", err);
+ pthread_kill(rt_task_thread, SIGUSR1);
+
+ rt_task_sleep(20000000);
+
+ err = rt_mutex_release(&prio_invert);
+ check_no_error("rt_mutex_release", err);
+
+ err = rt_task_join(&rt_task);
+ check_no_error("rt_task_join", err);
+
+ err = rt_mutex_delete(&prio_invert);
+ check_no_error("rt_mutex_delete", err);
+
+ err = rt_sem_delete(&send_signal);
+ check_no_error("rt_sem_delete", err);
+
+ if (wd) {
+ fprintf(wd, "%d", old_wd_value);
+ fclose(wd);
+ }
+
+ fprintf(stderr, "Test OK\n");
+
+ return 0;
+}
--
1.7.3.4
next reply other threads:[~2012-01-25 16:21 UTC|newest]
Thread overview: 19+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-01-25 16:21 Jan Kiszka [this message]
2012-01-25 16:35 ` [Xenomai-core] [PATCH] Add sigdebug unit test Gilles Chanteperdrix
2012-01-25 16:47 ` Jan Kiszka
2012-01-25 16:52 ` Jan Kiszka
2012-01-25 17:02 ` Gilles Chanteperdrix
2012-01-25 17:10 ` Jan Kiszka
2012-01-25 17:44 ` Gilles Chanteperdrix
2012-01-25 18:05 ` Jan Kiszka
2012-01-26 10:36 ` Jan Kiszka
2012-01-26 11:20 ` Philippe Gerum
2012-01-26 12:56 ` Jan Kiszka
2012-01-26 14:36 ` Jan Kiszka
2012-01-26 15:39 ` Jan Kiszka
2012-01-26 14:55 ` Gilles Chanteperdrix
2012-01-26 15:06 ` Jan Kiszka
2012-01-26 15:52 ` Gilles Chanteperdrix
2012-01-26 16:11 ` Jan Kiszka
2012-01-26 16:41 ` Gilles Chanteperdrix
2012-01-25 22:18 ` Gilles Chanteperdrix
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=4F202C11.70908@domain.hid \
--to=jan.kiszka@domain.hid \
--cc=xenomai@xenomai.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.