sigaltstack.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. #include <err.h>
  2. #include <inttypes.h>
  3. #include <signal.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #include <unistd.h>
  8. uint8_t* sig_stack;
  9. size_t sig_stack_size = SIGSTKSZ;
  10. _Atomic int count = 0;
  11. void handler(int signal, siginfo_t* info, void* ucontext) {
  12. int ret;
  13. count++;
  14. uint8_t a;
  15. printf("sig %d count %d goes off with sp=%p, sig_stack: [%p, %p)\n", signal, count, &a,
  16. sig_stack, sig_stack + sig_stack_size);
  17. if (sig_stack <= &a && &a < sig_stack + sig_stack_size) {
  18. printf("OK on signal stack\n");
  19. } else {
  20. printf("FAIL out of signal stack\n");
  21. }
  22. fflush(stdout);
  23. stack_t old;
  24. memset(&old, 0, sizeof(old));
  25. ret = sigaltstack(NULL, &old);
  26. if (ret < 0) {
  27. err(EXIT_FAILURE, "sigaltstack in handler");
  28. }
  29. if (old.ss_flags & SS_ONSTACK) {
  30. printf("OK on sigaltstack in handler\n");
  31. } else {
  32. printf("FAIL on sigaltstack in handler\n");
  33. }
  34. /*
  35. * raise SIGALRM during signal handling to test nested signals
  36. * (three-levels deep nesting just to be sure)
  37. */
  38. if (count <= 2) {
  39. sigset_t set;
  40. sigemptyset(&set);
  41. sigaddset(&set, SIGALRM);
  42. ret = sigprocmask(SIG_UNBLOCK, &set, NULL);
  43. if (ret) {
  44. err(EXIT_FAILURE, "sigprocmask");
  45. }
  46. raise(SIGALRM);
  47. }
  48. count--;
  49. }
  50. int main(int argc, char** argv) {
  51. int ret;
  52. sig_stack = malloc(sig_stack_size);
  53. if (sig_stack == NULL) {
  54. err(EXIT_FAILURE, "malloc");
  55. }
  56. stack_t ss = {
  57. .ss_sp = sig_stack,
  58. .ss_flags = 0,
  59. .ss_size = sig_stack_size,
  60. };
  61. stack_t old;
  62. memset(&old, 0xff, sizeof(old));
  63. ret = sigaltstack(&ss, &old);
  64. if (ret < 0) {
  65. err(EXIT_FAILURE, "sigaltstack");
  66. }
  67. if (old.ss_flags & SS_ONSTACK) {
  68. printf("FAIL on sigaltstack in main thread before alarm\n");
  69. } else {
  70. printf("OK on sigaltstack in main thread before alarm\n");
  71. }
  72. struct sigaction act;
  73. act.sa_sigaction = handler;
  74. sigemptyset(&act.sa_mask);
  75. act.sa_flags = SA_SIGINFO | SA_NODEFER | SA_ONSTACK;
  76. ret = sigaction(SIGALRM, &act, NULL);
  77. if (ret < 0) {
  78. err(EXIT_FAILURE, "sigaction");
  79. }
  80. printf("&act == %p\n", &act);
  81. fflush(stdout);
  82. alarm(1);
  83. pause();
  84. memset(&old, 0xff, sizeof(old));
  85. ret = sigaltstack(NULL, &old);
  86. if (ret < 0) {
  87. err(EXIT_FAILURE, "sigaltstack");
  88. }
  89. if (old.ss_flags & SS_ONSTACK) {
  90. printf("FAIL on sigaltstack in main thread\n");
  91. } else {
  92. printf("OK on sigaltstack in main thread\n");
  93. }
  94. printf("done exiting\n");
  95. fflush(stdout);
  96. return 0;
  97. }