init_signals.cc revision 11235
16226Snate@binkert.org/* 26226Snate@binkert.org * Copyright (c) 2012, 2015 ARM Limited 36226Snate@binkert.org * All rights reserved 46226Snate@binkert.org * 56226Snate@binkert.org * The license below extends only to copyright in the software and shall 66226Snate@binkert.org * not be construed as granting a license to any other intellectual 76226Snate@binkert.org * property including but not limited to intellectual property relating 86226Snate@binkert.org * to a hardware implementation of the functionality of the software 96226Snate@binkert.org * licensed hereunder. You may use the software subject to the license 106226Snate@binkert.org * terms below provided that you ensure that this notice is replicated 116226Snate@binkert.org * unmodified and in its entirety in all distributions of the software, 126226Snate@binkert.org * modified or unmodified, in source code or in binary form. 136226Snate@binkert.org * 146226Snate@binkert.org * Copyright (c) 2000-2005 The Regents of The University of Michigan 156226Snate@binkert.org * Copyright (c) 2008 The Hewlett-Packard Development Company 166226Snate@binkert.org * All rights reserved. 176226Snate@binkert.org * 186226Snate@binkert.org * Redistribution and use in source and binary forms, with or without 196226Snate@binkert.org * modification, are permitted provided that the following conditions are 206226Snate@binkert.org * met: redistributions of source code must retain the above copyright 216226Snate@binkert.org * notice, this list of conditions and the following disclaimer; 226226Snate@binkert.org * redistributions in binary form must reproduce the above copyright 236226Snate@binkert.org * notice, this list of conditions and the following disclaimer in the 246226Snate@binkert.org * documentation and/or other materials provided with the distribution; 256226Snate@binkert.org * neither the name of the copyright holders nor the names of its 266226Snate@binkert.org * contributors may be used to endorse or promote products derived from 276226Snate@binkert.org * this software without specific prior written permission. 286226Snate@binkert.org * 296226Snate@binkert.org * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 306226Snate@binkert.org * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 316226Snate@binkert.org * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 326226Snate@binkert.org * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 336226Snate@binkert.org * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 346226Snate@binkert.org * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 356226Snate@binkert.org * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 366226Snate@binkert.org * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 376226Snate@binkert.org * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 386226Snate@binkert.org * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 39 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 40 * 41 * Authors: Nathan Binkert 42 */ 43 44#include "sim/init_signals.hh" 45 46#include <sys/types.h> 47#include <unistd.h> 48 49#include <csignal> 50#include <iostream> 51#include <string> 52 53#include "base/atomicio.hh" 54#include "base/cprintf.hh" 55#include "sim/async.hh" 56#include "sim/backtrace.hh" 57#include "sim/core.hh" 58#include "sim/eventq.hh" 59 60using namespace std; 61 62// Use an separate stack for fatal signal handlers 63static uint8_t fatalSigStack[2 * SIGSTKSZ]; 64 65static bool 66setupAltStack() 67{ 68 stack_t stack; 69 stack.ss_sp = fatalSigStack; 70 stack.ss_size = sizeof(fatalSigStack); 71 stack.ss_flags = 0; 72 73 return sigaltstack(&stack, NULL) == 0; 74} 75 76static void 77installSignalHandler(int signal, void (*handler)(int sigtype), 78 int flags = SA_RESTART) 79{ 80 struct sigaction sa; 81 82 memset(&sa, 0, sizeof(sa)); 83 sigemptyset(&sa.sa_mask); 84 sa.sa_handler = handler; 85 sa.sa_flags = flags; 86 87 if (sigaction(signal, &sa, NULL) == -1) 88 panic("Failed to setup handler for signal %i\n", signal); 89} 90 91static void 92raiseFatalSignal(int signo) 93{ 94 // The signal handler should have been reset and unmasked (it was 95 // registered with SA_RESETHAND | SA_NODEFER), just raise the 96 // signal again to invoke the default handler. 97 pthread_kill(pthread_self(), signo); 98 99 // Something is really wrong if the process is alive at this 100 // point, manually try to exit it. 101 STATIC_ERR("Failed to execute default signal handler!\n"); 102 _exit(127); 103} 104 105/// Stats signal handler. 106void 107dumpStatsHandler(int sigtype) 108{ 109 async_event = true; 110 async_statdump = true; 111 /* Wake up some event queue to handle event */ 112 getEventQueue(0)->wakeup(); 113} 114 115void 116dumprstStatsHandler(int sigtype) 117{ 118 async_event = true; 119 async_statdump = true; 120 async_statreset = true; 121 /* Wake up some event queue to handle event */ 122 getEventQueue(0)->wakeup(); 123} 124 125/// Exit signal handler. 126void 127exitNowHandler(int sigtype) 128{ 129 async_event = true; 130 async_exit = true; 131 /* Wake up some event queue to handle event */ 132 getEventQueue(0)->wakeup(); 133} 134 135/// Abort signal handler. 136void 137abortHandler(int sigtype) 138{ 139 const EventQueue *const eq(curEventQueue()); 140 if (eq) { 141 ccprintf(cerr, "Program aborted at tick %llu\n", eq->getCurTick()); 142 } else { 143 STATIC_ERR("Program aborted\n\n"); 144 } 145 146 print_backtrace(); 147 raiseFatalSignal(sigtype); 148} 149 150/// Segmentation fault signal handler. 151static void 152segvHandler(int sigtype) 153{ 154 STATIC_ERR("gem5 has encountered a segmentation fault!\n\n"); 155 156 print_backtrace(); 157 raiseFatalSignal(SIGSEGV); 158} 159 160// Handle SIGIO 161static void 162ioHandler(int sigtype) 163{ 164 async_event = true; 165 async_io = true; 166 /* Wake up some event queue to handle event */ 167 getEventQueue(0)->wakeup(); 168} 169 170/* 171 * M5 can do several special things when various signals are sent. 172 * None are mandatory. 173 */ 174void 175initSignals() 176{ 177 // Floating point exceptions may happen on misspeculated paths, so 178 // ignore them 179 signal(SIGFPE, SIG_IGN); 180 181 // We use SIGTRAP sometimes for debugging 182 signal(SIGTRAP, SIG_IGN); 183 184 // Dump intermediate stats 185 installSignalHandler(SIGUSR1, dumpStatsHandler); 186 187 // Dump intermediate stats and reset them 188 installSignalHandler(SIGUSR2, dumprstStatsHandler); 189 190 // Exit cleanly on Interrupt (Ctrl-C) 191 installSignalHandler(SIGINT, exitNowHandler); 192 193 // Print the current cycle number and a backtrace on abort. Make 194 // sure the signal is unmasked and the handler reset when a signal 195 // is delivered to be able to invoke the default handler. 196 installSignalHandler(SIGABRT, abortHandler, SA_RESETHAND | SA_NODEFER); 197 198 // Setup a SIGSEGV handler with a private stack 199 if (setupAltStack()) { 200 installSignalHandler(SIGSEGV, segvHandler, 201 SA_RESETHAND | SA_NODEFER | SA_ONSTACK); 202 } else { 203 warn("Failed to setup stack for SIGSEGV handler, " 204 "using default signal handler.\n"); 205 } 206 207 // Install a SIGIO handler to handle asynchronous file IO. See the 208 // PollQueue class. 209 installSignalHandler(SIGIO, ioHandler); 210} 211 212