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