1*5ba1f45fSchristos /* Copyright (C) 2016-2024 Free Software Foundation, Inc. 28dffb485Schristos 38dffb485Schristos This file is part of GDB. 48dffb485Schristos 58dffb485Schristos This program is free software; you can redistribute it and/or modify 68dffb485Schristos it under the terms of the GNU General Public License as published by 78dffb485Schristos the Free Software Foundation; either version 3 of the License, or 88dffb485Schristos (at your option) any later version. 98dffb485Schristos 108dffb485Schristos This program is distributed in the hope that it will be useful, 118dffb485Schristos but WITHOUT ANY WARRANTY; without even the implied warranty of 128dffb485Schristos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 138dffb485Schristos GNU General Public License for more details. 148dffb485Schristos 158dffb485Schristos You should have received a copy of the GNU General Public License 168dffb485Schristos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 178dffb485Schristos 188dffb485Schristos #include "signals-state-save-restore.h" 198dffb485Schristos #include "gdbsupport/gdb-sigmask.h" 208dffb485Schristos 218dffb485Schristos #include <signal.h> 228dffb485Schristos 238dffb485Schristos /* The original signal actions and mask. */ 248dffb485Schristos 258dffb485Schristos #ifdef HAVE_SIGACTION 268dffb485Schristos static struct sigaction original_signal_actions[NSIG]; 278dffb485Schristos 288dffb485Schristos static sigset_t original_signal_mask; 298dffb485Schristos #endif 308dffb485Schristos 318dffb485Schristos /* See signals-state-save-restore.h. */ 328dffb485Schristos 338dffb485Schristos void 348dffb485Schristos save_original_signals_state (bool quiet) 358dffb485Schristos { 368dffb485Schristos #ifdef HAVE_SIGACTION 378dffb485Schristos int i; 388dffb485Schristos int res; 398dffb485Schristos 408dffb485Schristos res = gdb_sigmask (0, NULL, &original_signal_mask); 418dffb485Schristos if (res == -1) 428dffb485Schristos perror_with_name (("sigprocmask")); 438dffb485Schristos 448dffb485Schristos bool found_preinstalled = false; 458dffb485Schristos 468dffb485Schristos for (i = 1; i < NSIG; i++) 478dffb485Schristos { 488dffb485Schristos struct sigaction *oldact = &original_signal_actions[i]; 498dffb485Schristos 508dffb485Schristos res = sigaction (i, NULL, oldact); 518dffb485Schristos if (res == -1 && errno == EINVAL) 528dffb485Schristos { 538dffb485Schristos /* Some signal numbers in the range are invalid. */ 548dffb485Schristos continue; 558dffb485Schristos } 568dffb485Schristos else if (res == -1) 578dffb485Schristos perror_with_name (("sigaction")); 588dffb485Schristos 598dffb485Schristos /* If we find a custom signal handler already installed, then 608dffb485Schristos this function was called too late. This is a warning instead 618dffb485Schristos of an internal error because this can also happen if you 628dffb485Schristos LD_PRELOAD a library that installs a signal handler early via 638dffb485Schristos __attribute__((constructor)), like libSegFault.so. */ 648dffb485Schristos if (!quiet 658dffb485Schristos && oldact->sa_handler != SIG_DFL 668dffb485Schristos && oldact->sa_handler != SIG_IGN) 678dffb485Schristos { 688dffb485Schristos found_preinstalled = true; 698dffb485Schristos 708dffb485Schristos /* Use raw fprintf here because we're being called in early 718dffb485Schristos startup, before GDB's filtered streams are created. */ 728dffb485Schristos fprintf (stderr, 738dffb485Schristos _("warning: Found custom handler for signal " 748dffb485Schristos "%d (%s) preinstalled.\n"), i, 758dffb485Schristos strsignal (i)); 768dffb485Schristos } 778dffb485Schristos } 788dffb485Schristos 798dffb485Schristos if (found_preinstalled) 808dffb485Schristos { 818dffb485Schristos fprintf (stderr, _("\ 828dffb485Schristos Some signal dispositions inherited from the environment (SIG_DFL/SIG_IGN)\n\ 838dffb485Schristos won't be propagated to spawned programs.\n")); 848dffb485Schristos } 858dffb485Schristos #endif 868dffb485Schristos } 878dffb485Schristos 888dffb485Schristos /* See signals-state-save-restore.h. */ 898dffb485Schristos 908dffb485Schristos void 918dffb485Schristos restore_original_signals_state (void) 928dffb485Schristos { 938dffb485Schristos #ifdef HAVE_SIGACTION 948dffb485Schristos int i; 958dffb485Schristos int res; 968dffb485Schristos 978dffb485Schristos for (i = 1; i < NSIG; i++) 988dffb485Schristos { 998dffb485Schristos res = sigaction (i, &original_signal_actions[i], NULL); 1008dffb485Schristos if (res == -1 && errno == EINVAL) 1018dffb485Schristos { 1028dffb485Schristos /* Some signal numbers in the range are invalid. */ 1038dffb485Schristos continue; 1048dffb485Schristos } 1058dffb485Schristos else if (res == -1) 1068dffb485Schristos perror_with_name (("sigaction")); 1078dffb485Schristos } 1088dffb485Schristos 1098dffb485Schristos res = gdb_sigmask (SIG_SETMASK, &original_signal_mask, NULL); 1108dffb485Schristos if (res == -1) 1118dffb485Schristos perror_with_name (("sigprocmask")); 1128dffb485Schristos #endif 1138dffb485Schristos } 114