From ceabbfe181599bca83d81e087a229797e472c09c Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Wed, 3 Jun 2020 15:04:09 -0700 Subject: [PATCH] Test signals (#140) * Add a basic testcase for emulated signals. * Add a testcase for raise(SIGABRT). * Fix style. * Actually use all of the C-standard-required signals. * Update expected stderr. * Use the right version of this test file. Co-authored-by: Pat Hickey --- tests/general/sigabrt.c | 10 +++ tests/general/sigabrt.c.exit_status.expected | 1 + tests/general/sigabrt.c.options | 1 + tests/general/sigabrt.c.stderr.expected | 8 ++ .../general/sigabrt.c.stderr.expected.filter | 7 ++ tests/general/signals.c | 79 +++++++++++++++++++ tests/general/signals.c.options | 1 + tests/general/signals.c.stderr.expected | 1 + tests/general/signals.c.stdout.expected | 4 + 9 files changed, 112 insertions(+) create mode 100644 tests/general/sigabrt.c create mode 100644 tests/general/sigabrt.c.exit_status.expected create mode 100644 tests/general/sigabrt.c.options create mode 100644 tests/general/sigabrt.c.stderr.expected create mode 100755 tests/general/sigabrt.c.stderr.expected.filter create mode 100644 tests/general/signals.c create mode 100644 tests/general/signals.c.options create mode 100644 tests/general/signals.c.stderr.expected create mode 100644 tests/general/signals.c.stdout.expected diff --git a/tests/general/sigabrt.c b/tests/general/sigabrt.c new file mode 100644 index 0000000..22569be --- /dev/null +++ b/tests/general/sigabrt.c @@ -0,0 +1,10 @@ +#include +#include +#include + +int main(void) { + fprintf(stderr, "raising SIGABRT...\n"); + raise(SIGABRT); + fprintf(stderr, "oops!\n"); + return EXIT_FAILURE; +} diff --git a/tests/general/sigabrt.c.exit_status.expected b/tests/general/sigabrt.c.exit_status.expected new file mode 100644 index 0000000..405e2af --- /dev/null +++ b/tests/general/sigabrt.c.exit_status.expected @@ -0,0 +1 @@ +134 diff --git a/tests/general/sigabrt.c.options b/tests/general/sigabrt.c.options new file mode 100644 index 0000000..4f07a3e --- /dev/null +++ b/tests/general/sigabrt.c.options @@ -0,0 +1 @@ +-D_WASI_EMULATED_SIGNAL -lwasi-emulated-signal diff --git a/tests/general/sigabrt.c.stderr.expected b/tests/general/sigabrt.c.stderr.expected new file mode 100644 index 0000000..edba63e --- /dev/null +++ b/tests/general/sigabrt.c.stderr.expected @@ -0,0 +1,8 @@ +raising SIGABRT... +Program recieved fatal signal: Aborted +Error: failed to run main module `sigabrt.c.---.wasm` + +Caused by: + 0: failed to invoke `_start` + 1: wasm trap: unreachable, source location: @---- + wasm backtrace: diff --git a/tests/general/sigabrt.c.stderr.expected.filter b/tests/general/sigabrt.c.stderr.expected.filter new file mode 100755 index 0000000..425b060 --- /dev/null +++ b/tests/general/sigabrt.c.stderr.expected.filter @@ -0,0 +1,7 @@ +#!/bin/bash +set -euo pipefail + +cat \ + | sed -e 's/main module `sigabrt\.c\.[^`]*\.wasm`/main module `sigabrt.c.---.wasm`/' \ + | sed -e 's/source location: @[[:xdigit:]]*$/source location: @----/' \ + | head -n 6 diff --git a/tests/general/signals.c b/tests/general/signals.c new file mode 100644 index 0000000..27c8e9e --- /dev/null +++ b/tests/general/signals.c @@ -0,0 +1,79 @@ +#include +#include +#include +#include +#include +#include + +// Make sure this exists. +#include + +volatile sig_atomic_t flag = 0; + +static void handler(int n) { + // This is undefined behavior by the spec, but this is just a testcase. + fflush(stdout); + printf("handler for signal %s\n", strsignal(n)); + fflush(stdout); + flag = 1; +} + +int main(void) { + // Test various raise cases that don't abort. + assert(raise(SIGCHLD) == 0); +#ifdef SIGCLD + assert(raise(SIGCLD) == 0); +#endif + assert(raise(SIGURG) == 0); + assert(raise(SIGWINCH) == 0); + + errno = 0; + assert(raise(_NSIG) == -1 && errno == EINVAL); + + // Test psignal. + psignal(SIGINT, "psignal message for SIGINT"); + + // Test strsignal. + printf("strsignal for SIGHUP: '%s'\n", strsignal(SIGHUP)); + + // Some signals can't be ignored. + errno = 0; + assert(signal(SIGKILL, SIG_IGN) == SIG_ERR && errno == EINVAL); + errno = 0; + assert(signal(SIGSTOP, SIG_IGN) == SIG_ERR && errno == EINVAL); + + // Test that all the C-standard-required signals can be + // ignored with `SIG_IGN`. + int some_fatal_sigs[] = { + SIGINT, SIGABRT, SIGFPE, SIGILL, SIGSEGV, SIGTERM + }; + for (size_t i = 0; + i < sizeof(some_fatal_sigs) / sizeof(some_fatal_sigs[0]); + ++i) + { + int sig = some_fatal_sigs[i]; + assert(signal(sig, SIG_IGN) == SIG_DFL); + raise(sig); + assert(signal(sig, SIG_DFL) == SIG_IGN); + assert(signal(sig, SIG_DFL) == SIG_DFL); + } + + // Install a handler and invoke it. + printf("beginning handler test:\n"); + assert(signal(SIGWINCH, handler) == SIG_DFL); + fflush(stdout); + assert(raise(SIGWINCH) == 0); + fflush(stdout); + assert(flag == 1); + printf("finished handler test\n"); + + // Check various API invariants. + assert(signal(SIGWINCH, SIG_IGN) == handler); + assert(raise(SIGWINCH) == 0); + assert(signal(SIGWINCH, SIG_DFL) == SIG_IGN); + assert(raise(SIGWINCH) == 0); + assert(signal(SIGWINCH, SIG_DFL) == SIG_DFL); + assert(raise(SIGWINCH) == 0); + + return EXIT_SUCCESS; +} diff --git a/tests/general/signals.c.options b/tests/general/signals.c.options new file mode 100644 index 0000000..4f07a3e --- /dev/null +++ b/tests/general/signals.c.options @@ -0,0 +1 @@ +-D_WASI_EMULATED_SIGNAL -lwasi-emulated-signal diff --git a/tests/general/signals.c.stderr.expected b/tests/general/signals.c.stderr.expected new file mode 100644 index 0000000..f1b48ab --- /dev/null +++ b/tests/general/signals.c.stderr.expected @@ -0,0 +1 @@ +psignal message for SIGINT: Interrupt diff --git a/tests/general/signals.c.stdout.expected b/tests/general/signals.c.stdout.expected new file mode 100644 index 0000000..b35f256 --- /dev/null +++ b/tests/general/signals.c.stdout.expected @@ -0,0 +1,4 @@ +strsignal for SIGHUP: 'Hangup' +beginning handler test: +handler for signal Window changed +finished handler test