123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108 |
- #include <err.h>
- #include <inttypes.h>
- #include <signal.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- uint8_t* sig_stack;
- size_t sig_stack_size = SIGSTKSZ;
- _Atomic int count = 0;
- void handler(int signal, siginfo_t* info, void* ucontext) {
- int ret;
- count++;
- uint8_t a;
- printf("sig %d count %d goes off with sp=%p, sig_stack: [%p, %p)\n", signal, count, &a,
- sig_stack, sig_stack + sig_stack_size);
- if (sig_stack <= &a && &a < sig_stack + sig_stack_size) {
- printf("OK on signal stack\n");
- } else {
- printf("FAIL out of signal stack\n");
- }
- fflush(stdout);
- stack_t old;
- memset(&old, 0, sizeof(old));
- ret = sigaltstack(NULL, &old);
- if (ret < 0) {
- err(EXIT_FAILURE, "sigaltstack in handler");
- }
- if (old.ss_flags & SS_ONSTACK) {
- printf("OK on sigaltstack in handler\n");
- } else {
- printf("FAIL on sigaltstack in handler\n");
- }
- /*
- * raise SIGALRM during signal handling to test nested signals
- * (three-levels deep nesting just to be sure)
- */
- if (count <= 2) {
- sigset_t set;
- sigemptyset(&set);
- sigaddset(&set, SIGALRM);
- ret = sigprocmask(SIG_UNBLOCK, &set, NULL);
- if (ret) {
- err(EXIT_FAILURE, "sigprocmask");
- }
- raise(SIGALRM);
- }
- count--;
- }
- int main(int argc, char** argv) {
- int ret;
- sig_stack = malloc(sig_stack_size);
- if (sig_stack == NULL) {
- err(EXIT_FAILURE, "malloc");
- }
- stack_t ss = {
- .ss_sp = sig_stack,
- .ss_flags = 0,
- .ss_size = sig_stack_size,
- };
- stack_t old;
- memset(&old, 0xff, sizeof(old));
- ret = sigaltstack(&ss, &old);
- if (ret < 0) {
- err(EXIT_FAILURE, "sigaltstack");
- }
- if (old.ss_flags & SS_ONSTACK) {
- printf("FAIL on sigaltstack in main thread before alarm\n");
- } else {
- printf("OK on sigaltstack in main thread before alarm\n");
- }
- struct sigaction act;
- act.sa_sigaction = handler;
- sigemptyset(&act.sa_mask);
- act.sa_flags = SA_SIGINFO | SA_NODEFER | SA_ONSTACK;
- ret = sigaction(SIGALRM, &act, NULL);
- if (ret < 0) {
- err(EXIT_FAILURE, "sigaction");
- }
- printf("&act == %p\n", &act);
- fflush(stdout);
- alarm(1);
- pause();
- memset(&old, 0xff, sizeof(old));
- ret = sigaltstack(NULL, &old);
- if (ret < 0) {
- err(EXIT_FAILURE, "sigaltstack");
- }
- if (old.ss_flags & SS_ONSTACK) {
- printf("FAIL on sigaltstack in main thread\n");
- } else {
- printf("OK on sigaltstack in main thread\n");
- }
- printf("done exiting\n");
- fflush(stdout);
- return 0;
- }
|