siginfo-example.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108
  1. /*
  2. * Copyright (c) 2020-2022, the SerenityOS developers.
  3. *
  4. * SPDX-License-Identifier: BSD-2-Clause
  5. */
  6. #include <signal.h>
  7. #include <stdio.h>
  8. #include <sys/types.h>
  9. #include <sys/wait.h>
  10. #include <unistd.h>
  11. // Supposed to use volatile everywhere here but good lord does C++ make that a pain
  12. volatile sig_atomic_t saved_signal;
  13. volatile siginfo_t saved_siginfo;
  14. volatile ucontext_t saved_ucontext;
  15. siginfo_t* sig_info_addr;
  16. ucontext_t* ucontext_addr;
  17. void* stack_ptr;
  18. volatile bool signal_was_delivered = false;
  19. static void signal_handler(int sig, siginfo_t* sig_info, void* u_context)
  20. {
  21. int x;
  22. stack_ptr = &x;
  23. signal_was_delivered = true;
  24. saved_signal = sig;
  25. // grumble grumble, assignment operator on volatile types not a thing
  26. // grumble grumble more, can't memcpy voltile either, that casts away volatile
  27. // grumble grumble even more, can't std::copy to volatile.
  28. // screw it, just write all the fields
  29. sig_info_addr = sig_info;
  30. saved_siginfo.si_status = sig_info->si_status;
  31. saved_siginfo.si_signo = sig_info->si_signo;
  32. saved_siginfo.si_code = sig_info->si_code;
  33. saved_siginfo.si_pid = sig_info->si_pid;
  34. saved_siginfo.si_uid = sig_info->si_uid;
  35. saved_siginfo.si_value.sival_int = sig_info->si_value.sival_int;
  36. auto user_context = (ucontext_t*)u_context;
  37. ucontext_addr = user_context;
  38. saved_ucontext.uc_link = user_context->uc_link;
  39. saved_ucontext.uc_sigmask = user_context->uc_sigmask;
  40. saved_ucontext.uc_stack.ss_sp = user_context->uc_stack.ss_sp;
  41. saved_ucontext.uc_stack.ss_size = user_context->uc_stack.ss_size;
  42. saved_ucontext.uc_stack.ss_flags = user_context->uc_stack.ss_flags;
  43. // saved_ucontext.uc_mcontext = user_context->uc_mcontext;
  44. }
  45. static int print_signal_results()
  46. {
  47. if (!signal_was_delivered) {
  48. fprintf(stderr, "Where was my signal bro?\n");
  49. return 2;
  50. }
  51. sig_atomic_t read_the_signal = saved_signal;
  52. siginfo_t read_the_siginfo = {};
  53. read_the_siginfo.si_status = saved_siginfo.si_status;
  54. read_the_siginfo.si_signo = saved_siginfo.si_signo;
  55. read_the_siginfo.si_code = saved_siginfo.si_code;
  56. read_the_siginfo.si_pid = saved_siginfo.si_pid;
  57. read_the_siginfo.si_uid = saved_siginfo.si_uid;
  58. read_the_siginfo.si_value.sival_int = saved_siginfo.si_value.sival_int;
  59. ucontext_t read_the_ucontext = {};
  60. read_the_ucontext.uc_link = saved_ucontext.uc_link;
  61. read_the_ucontext.uc_sigmask = saved_ucontext.uc_sigmask;
  62. read_the_ucontext.uc_stack.ss_sp = saved_ucontext.uc_stack.ss_sp;
  63. read_the_ucontext.uc_stack.ss_size = saved_ucontext.uc_stack.ss_size;
  64. read_the_ucontext.uc_stack.ss_flags = saved_ucontext.uc_stack.ss_flags;
  65. // read_the_ucontext.uc_mcontext = saved_ucontext.uc_mcontext;
  66. printf("Handled signal: %d\n", read_the_signal);
  67. printf("Stack sorta started as %p\n", stack_ptr);
  68. printf("Siginfo was stored at %p:\n", sig_info_addr);
  69. printf("\tsi_signo: %d\n", read_the_siginfo.si_signo);
  70. printf("\tsi_code, %x\n", read_the_siginfo.si_code);
  71. printf("\tsi_pid, %d\n", read_the_siginfo.si_pid);
  72. printf("\tsi_uid, %d\n", read_the_siginfo.si_uid);
  73. printf("\tsi_status, %x\n", read_the_siginfo.si_status);
  74. printf("\tsi_value.sival_int, %x\n", read_the_siginfo.si_value.sival_int);
  75. printf("ucontext was stored at %p:\n", ucontext_addr);
  76. printf("\tuc_link, %p\n", read_the_ucontext.uc_link);
  77. printf("\tuc_sigmask, %d\n", read_the_ucontext.uc_sigmask);
  78. printf("\tuc_stack.ss_sp, %p\n", read_the_ucontext.uc_stack.ss_sp);
  79. printf("\tuc_stack.ss_size, %zu\n", read_the_ucontext.uc_stack.ss_size);
  80. printf("\tuc_stack.ss_flags, %d\n", read_the_ucontext.uc_stack.ss_flags);
  81. // printf("\tuc_mcontext, %d\n", read_the_ucontext.uc_mcontext);
  82. return 0;
  83. }
  84. int main()
  85. {
  86. struct sigaction action = {};
  87. action.sa_flags = SA_SIGINFO;
  88. sigemptyset(&action.sa_mask);
  89. action.sa_sigaction = signal_handler;
  90. for (size_t i = 0; i < NSIG; ++i)
  91. (void)sigaction(i, &action, nullptr);
  92. printf("Sleeping for a long time waiting for kill -<N> %d\n", getpid());
  93. sleep(1000);
  94. return print_signal_results();
  95. }