signals-state-save-restore.cc 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. /* Copyright (C) 2016-2022 Free Software Foundation, Inc.
  2. This file is part of GDB.
  3. This program is free software; you can redistribute it and/or modify
  4. it under the terms of the GNU General Public License as published by
  5. the Free Software Foundation; either version 3 of the License, or
  6. (at your option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License
  12. along with this program. If not, see <http://www.gnu.org/licenses/>. */
  13. #include "common-defs.h"
  14. #include "signals-state-save-restore.h"
  15. #include "gdbsupport/gdb-sigmask.h"
  16. #include <signal.h>
  17. /* The original signal actions and mask. */
  18. #ifdef HAVE_SIGACTION
  19. static struct sigaction original_signal_actions[NSIG];
  20. static sigset_t original_signal_mask;
  21. #endif
  22. /* See signals-state-save-restore.h. */
  23. void
  24. save_original_signals_state (bool quiet)
  25. {
  26. #ifdef HAVE_SIGACTION
  27. int i;
  28. int res;
  29. res = gdb_sigmask (0, NULL, &original_signal_mask);
  30. if (res == -1)
  31. perror_with_name (("sigprocmask"));
  32. bool found_preinstalled = false;
  33. for (i = 1; i < NSIG; i++)
  34. {
  35. struct sigaction *oldact = &original_signal_actions[i];
  36. res = sigaction (i, NULL, oldact);
  37. if (res == -1 && errno == EINVAL)
  38. {
  39. /* Some signal numbers in the range are invalid. */
  40. continue;
  41. }
  42. else if (res == -1)
  43. perror_with_name (("sigaction"));
  44. /* If we find a custom signal handler already installed, then
  45. this function was called too late. This is a warning instead
  46. of an internal error because this can also happen if you
  47. LD_PRELOAD a library that installs a signal handler early via
  48. __attribute__((constructor)), like libSegFault.so. */
  49. if (!quiet
  50. && oldact->sa_handler != SIG_DFL
  51. && oldact->sa_handler != SIG_IGN)
  52. {
  53. found_preinstalled = true;
  54. /* Use raw fprintf here because we're being called in early
  55. startup, before GDB's filtered streams are created. */
  56. fprintf (stderr,
  57. _("warning: Found custom handler for signal "
  58. "%d (%s) preinstalled.\n"), i,
  59. strsignal (i));
  60. }
  61. }
  62. if (found_preinstalled)
  63. {
  64. fprintf (stderr, _("\
  65. Some signal dispositions inherited from the environment (SIG_DFL/SIG_IGN)\n\
  66. won't be propagated to spawned programs.\n"));
  67. }
  68. #endif
  69. }
  70. /* See signals-state-save-restore.h. */
  71. void
  72. restore_original_signals_state (void)
  73. {
  74. #ifdef HAVE_SIGACTION
  75. int i;
  76. int res;
  77. for (i = 1; i < NSIG; i++)
  78. {
  79. res = sigaction (i, &original_signal_actions[i], NULL);
  80. if (res == -1 && errno == EINVAL)
  81. {
  82. /* Some signal numbers in the range are invalid. */
  83. continue;
  84. }
  85. else if (res == -1)
  86. perror_with_name (("sigaction"));
  87. }
  88. res = gdb_sigmask (SIG_SETMASK, &original_signal_mask, NULL);
  89. if (res == -1)
  90. perror_with_name (("sigprocmask"));
  91. #endif
  92. }