init_signals.cc revision 12334
110453SAndrew.Bardsley@arm.com/* 211235Sandreas.sandberg@arm.com * Copyright (c) 2012, 2015 ARM Limited 310453SAndrew.Bardsley@arm.com * All rights reserved 410453SAndrew.Bardsley@arm.com * 510453SAndrew.Bardsley@arm.com * The license below extends only to copyright in the software and shall 610453SAndrew.Bardsley@arm.com * not be construed as granting a license to any other intellectual 710453SAndrew.Bardsley@arm.com * property including but not limited to intellectual property relating 810453SAndrew.Bardsley@arm.com * to a hardware implementation of the functionality of the software 910453SAndrew.Bardsley@arm.com * licensed hereunder. You may use the software subject to the license 1010453SAndrew.Bardsley@arm.com * terms below provided that you ensure that this notice is replicated 1110453SAndrew.Bardsley@arm.com * unmodified and in its entirety in all distributions of the software, 1210453SAndrew.Bardsley@arm.com * modified or unmodified, in source code or in binary form. 1310453SAndrew.Bardsley@arm.com * 1410453SAndrew.Bardsley@arm.com * Copyright (c) 2000-2005 The Regents of The University of Michigan 1510453SAndrew.Bardsley@arm.com * Copyright (c) 2008 The Hewlett-Packard Development Company 1610453SAndrew.Bardsley@arm.com * All rights reserved. 1710453SAndrew.Bardsley@arm.com * 1810453SAndrew.Bardsley@arm.com * Redistribution and use in source and binary forms, with or without 1910453SAndrew.Bardsley@arm.com * modification, are permitted provided that the following conditions are 2010453SAndrew.Bardsley@arm.com * met: redistributions of source code must retain the above copyright 2110453SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer; 2210453SAndrew.Bardsley@arm.com * redistributions in binary form must reproduce the above copyright 2310453SAndrew.Bardsley@arm.com * notice, this list of conditions and the following disclaimer in the 2410453SAndrew.Bardsley@arm.com * documentation and/or other materials provided with the distribution; 2510453SAndrew.Bardsley@arm.com * neither the name of the copyright holders nor the names of its 2610453SAndrew.Bardsley@arm.com * contributors may be used to endorse or promote products derived from 2710453SAndrew.Bardsley@arm.com * this software without specific prior written permission. 2810453SAndrew.Bardsley@arm.com * 2910453SAndrew.Bardsley@arm.com * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 3010453SAndrew.Bardsley@arm.com * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 3110453SAndrew.Bardsley@arm.com * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 3210453SAndrew.Bardsley@arm.com * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 3310453SAndrew.Bardsley@arm.com * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 3410453SAndrew.Bardsley@arm.com * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 3510453SAndrew.Bardsley@arm.com * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 3610453SAndrew.Bardsley@arm.com * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 3710453SAndrew.Bardsley@arm.com * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 3810453SAndrew.Bardsley@arm.com * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 3910453SAndrew.Bardsley@arm.com * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 4010453SAndrew.Bardsley@arm.com * 4110453SAndrew.Bardsley@arm.com * Authors: Nathan Binkert 4210453SAndrew.Bardsley@arm.com */ 4310453SAndrew.Bardsley@arm.com 4411235Sandreas.sandberg@arm.com#include "sim/init_signals.hh" 4511235Sandreas.sandberg@arm.com 4611235Sandreas.sandberg@arm.com#include <sys/types.h> 4711235Sandreas.sandberg@arm.com#include <unistd.h> 4811235Sandreas.sandberg@arm.com 4910453SAndrew.Bardsley@arm.com#include <csignal> 5010453SAndrew.Bardsley@arm.com#include <iostream> 5110453SAndrew.Bardsley@arm.com#include <string> 5210453SAndrew.Bardsley@arm.com 5312203Sbaz21@cam.ac.uk#if defined(__FreeBSD__) 5412203Sbaz21@cam.ac.uk#include <sys/param.h> 5512203Sbaz21@cam.ac.uk 5612203Sbaz21@cam.ac.uk#endif 5712203Sbaz21@cam.ac.uk 5811235Sandreas.sandberg@arm.com#include "base/atomicio.hh" 5910453SAndrew.Bardsley@arm.com#include "base/cprintf.hh" 6012334Sgabeblack@google.com#include "base/logging.hh" 6110453SAndrew.Bardsley@arm.com#include "sim/async.hh" 6211235Sandreas.sandberg@arm.com#include "sim/backtrace.hh" 6310453SAndrew.Bardsley@arm.com#include "sim/core.hh" 6410476Sandreas.hansson@arm.com#include "sim/eventq.hh" 6510453SAndrew.Bardsley@arm.com 6610453SAndrew.Bardsley@arm.comusing namespace std; 6710453SAndrew.Bardsley@arm.com 6811235Sandreas.sandberg@arm.com// Use an separate stack for fatal signal handlers 6911235Sandreas.sandberg@arm.comstatic uint8_t fatalSigStack[2 * SIGSTKSZ]; 7011235Sandreas.sandberg@arm.com 7111235Sandreas.sandberg@arm.comstatic bool 7211235Sandreas.sandberg@arm.comsetupAltStack() 7311235Sandreas.sandberg@arm.com{ 7411235Sandreas.sandberg@arm.com stack_t stack; 7512203Sbaz21@cam.ac.uk#if defined(__FreeBSD__) && (__FreeBSD_version < 1100097) 7612203Sbaz21@cam.ac.uk stack.ss_sp = (char *)fatalSigStack; 7712203Sbaz21@cam.ac.uk#else 7811235Sandreas.sandberg@arm.com stack.ss_sp = fatalSigStack; 7912203Sbaz21@cam.ac.uk#endif 8011235Sandreas.sandberg@arm.com stack.ss_size = sizeof(fatalSigStack); 8111235Sandreas.sandberg@arm.com stack.ss_flags = 0; 8211235Sandreas.sandberg@arm.com 8311235Sandreas.sandberg@arm.com return sigaltstack(&stack, NULL) == 0; 8411235Sandreas.sandberg@arm.com} 8511235Sandreas.sandberg@arm.com 8611235Sandreas.sandberg@arm.comstatic void 8711235Sandreas.sandberg@arm.cominstallSignalHandler(int signal, void (*handler)(int sigtype), 8811235Sandreas.sandberg@arm.com int flags = SA_RESTART) 8911235Sandreas.sandberg@arm.com{ 9011235Sandreas.sandberg@arm.com struct sigaction sa; 9111235Sandreas.sandberg@arm.com 9211235Sandreas.sandberg@arm.com memset(&sa, 0, sizeof(sa)); 9311235Sandreas.sandberg@arm.com sigemptyset(&sa.sa_mask); 9411235Sandreas.sandberg@arm.com sa.sa_handler = handler; 9511235Sandreas.sandberg@arm.com sa.sa_flags = flags; 9611235Sandreas.sandberg@arm.com 9711235Sandreas.sandberg@arm.com if (sigaction(signal, &sa, NULL) == -1) 9811235Sandreas.sandberg@arm.com panic("Failed to setup handler for signal %i\n", signal); 9911235Sandreas.sandberg@arm.com} 10011235Sandreas.sandberg@arm.com 10111235Sandreas.sandberg@arm.comstatic void 10211235Sandreas.sandberg@arm.comraiseFatalSignal(int signo) 10311235Sandreas.sandberg@arm.com{ 10411235Sandreas.sandberg@arm.com // The signal handler should have been reset and unmasked (it was 10511235Sandreas.sandberg@arm.com // registered with SA_RESETHAND | SA_NODEFER), just raise the 10611235Sandreas.sandberg@arm.com // signal again to invoke the default handler. 10711235Sandreas.sandberg@arm.com pthread_kill(pthread_self(), signo); 10811235Sandreas.sandberg@arm.com 10911235Sandreas.sandberg@arm.com // Something is really wrong if the process is alive at this 11011235Sandreas.sandberg@arm.com // point, manually try to exit it. 11111235Sandreas.sandberg@arm.com STATIC_ERR("Failed to execute default signal handler!\n"); 11211235Sandreas.sandberg@arm.com _exit(127); 11311235Sandreas.sandberg@arm.com} 11411235Sandreas.sandberg@arm.com 11510453SAndrew.Bardsley@arm.com/// Stats signal handler. 11610453SAndrew.Bardsley@arm.comvoid 11710453SAndrew.Bardsley@arm.comdumpStatsHandler(int sigtype) 11810453SAndrew.Bardsley@arm.com{ 11910453SAndrew.Bardsley@arm.com async_event = true; 12010453SAndrew.Bardsley@arm.com async_statdump = true; 12110476Sandreas.hansson@arm.com /* Wake up some event queue to handle event */ 12210476Sandreas.hansson@arm.com getEventQueue(0)->wakeup(); 12310453SAndrew.Bardsley@arm.com} 12410453SAndrew.Bardsley@arm.com 12510453SAndrew.Bardsley@arm.comvoid 12610453SAndrew.Bardsley@arm.comdumprstStatsHandler(int sigtype) 12710453SAndrew.Bardsley@arm.com{ 12810453SAndrew.Bardsley@arm.com async_event = true; 12910453SAndrew.Bardsley@arm.com async_statdump = true; 13010453SAndrew.Bardsley@arm.com async_statreset = true; 13110476Sandreas.hansson@arm.com /* Wake up some event queue to handle event */ 13210476Sandreas.hansson@arm.com getEventQueue(0)->wakeup(); 13310453SAndrew.Bardsley@arm.com} 13410453SAndrew.Bardsley@arm.com 13510453SAndrew.Bardsley@arm.com/// Exit signal handler. 13610453SAndrew.Bardsley@arm.comvoid 13710453SAndrew.Bardsley@arm.comexitNowHandler(int sigtype) 13810453SAndrew.Bardsley@arm.com{ 13910453SAndrew.Bardsley@arm.com async_event = true; 14010453SAndrew.Bardsley@arm.com async_exit = true; 14110476Sandreas.hansson@arm.com /* Wake up some event queue to handle event */ 14210476Sandreas.hansson@arm.com getEventQueue(0)->wakeup(); 14310453SAndrew.Bardsley@arm.com} 14410453SAndrew.Bardsley@arm.com 14510453SAndrew.Bardsley@arm.com/// Abort signal handler. 14610453SAndrew.Bardsley@arm.comvoid 14710453SAndrew.Bardsley@arm.comabortHandler(int sigtype) 14810453SAndrew.Bardsley@arm.com{ 14911235Sandreas.sandberg@arm.com const EventQueue *const eq(curEventQueue()); 15011235Sandreas.sandberg@arm.com if (eq) { 15111235Sandreas.sandberg@arm.com ccprintf(cerr, "Program aborted at tick %llu\n", eq->getCurTick()); 15211235Sandreas.sandberg@arm.com } else { 15311235Sandreas.sandberg@arm.com STATIC_ERR("Program aborted\n\n"); 15411235Sandreas.sandberg@arm.com } 15511235Sandreas.sandberg@arm.com 15611235Sandreas.sandberg@arm.com print_backtrace(); 15711235Sandreas.sandberg@arm.com raiseFatalSignal(sigtype); 15811235Sandreas.sandberg@arm.com} 15911235Sandreas.sandberg@arm.com 16011235Sandreas.sandberg@arm.com/// Segmentation fault signal handler. 16111235Sandreas.sandberg@arm.comstatic void 16211235Sandreas.sandberg@arm.comsegvHandler(int sigtype) 16311235Sandreas.sandberg@arm.com{ 16411235Sandreas.sandberg@arm.com STATIC_ERR("gem5 has encountered a segmentation fault!\n\n"); 16511235Sandreas.sandberg@arm.com 16611235Sandreas.sandberg@arm.com print_backtrace(); 16711235Sandreas.sandberg@arm.com raiseFatalSignal(SIGSEGV); 16810453SAndrew.Bardsley@arm.com} 16910453SAndrew.Bardsley@arm.com 17010453SAndrew.Bardsley@arm.com// Handle SIGIO 17110453SAndrew.Bardsley@arm.comstatic void 17210453SAndrew.Bardsley@arm.comioHandler(int sigtype) 17310453SAndrew.Bardsley@arm.com{ 17410453SAndrew.Bardsley@arm.com async_event = true; 17510453SAndrew.Bardsley@arm.com async_io = true; 17610476Sandreas.hansson@arm.com /* Wake up some event queue to handle event */ 17710476Sandreas.hansson@arm.com getEventQueue(0)->wakeup(); 17810453SAndrew.Bardsley@arm.com} 17910453SAndrew.Bardsley@arm.com 18010453SAndrew.Bardsley@arm.com/* 18110453SAndrew.Bardsley@arm.com * M5 can do several special things when various signals are sent. 18210453SAndrew.Bardsley@arm.com * None are mandatory. 18310453SAndrew.Bardsley@arm.com */ 18410453SAndrew.Bardsley@arm.comvoid 18510453SAndrew.Bardsley@arm.cominitSignals() 18610453SAndrew.Bardsley@arm.com{ 18710453SAndrew.Bardsley@arm.com // Floating point exceptions may happen on misspeculated paths, so 18810453SAndrew.Bardsley@arm.com // ignore them 18910453SAndrew.Bardsley@arm.com signal(SIGFPE, SIG_IGN); 19010453SAndrew.Bardsley@arm.com 19110453SAndrew.Bardsley@arm.com // Dump intermediate stats 19210453SAndrew.Bardsley@arm.com installSignalHandler(SIGUSR1, dumpStatsHandler); 19310453SAndrew.Bardsley@arm.com 19410453SAndrew.Bardsley@arm.com // Dump intermediate stats and reset them 19510453SAndrew.Bardsley@arm.com installSignalHandler(SIGUSR2, dumprstStatsHandler); 19610453SAndrew.Bardsley@arm.com 19710453SAndrew.Bardsley@arm.com // Exit cleanly on Interrupt (Ctrl-C) 19810453SAndrew.Bardsley@arm.com installSignalHandler(SIGINT, exitNowHandler); 19910453SAndrew.Bardsley@arm.com 20011235Sandreas.sandberg@arm.com // Print the current cycle number and a backtrace on abort. Make 20111235Sandreas.sandberg@arm.com // sure the signal is unmasked and the handler reset when a signal 20211235Sandreas.sandberg@arm.com // is delivered to be able to invoke the default handler. 20311235Sandreas.sandberg@arm.com installSignalHandler(SIGABRT, abortHandler, SA_RESETHAND | SA_NODEFER); 20411235Sandreas.sandberg@arm.com 20511235Sandreas.sandberg@arm.com // Setup a SIGSEGV handler with a private stack 20611235Sandreas.sandberg@arm.com if (setupAltStack()) { 20711235Sandreas.sandberg@arm.com installSignalHandler(SIGSEGV, segvHandler, 20811235Sandreas.sandberg@arm.com SA_RESETHAND | SA_NODEFER | SA_ONSTACK); 20911235Sandreas.sandberg@arm.com } else { 21011235Sandreas.sandberg@arm.com warn("Failed to setup stack for SIGSEGV handler, " 21111235Sandreas.sandberg@arm.com "using default signal handler.\n"); 21211235Sandreas.sandberg@arm.com } 21310453SAndrew.Bardsley@arm.com 21410453SAndrew.Bardsley@arm.com // Install a SIGIO handler to handle asynchronous file IO. See the 21510453SAndrew.Bardsley@arm.com // PollQueue class. 21610453SAndrew.Bardsley@arm.com installSignalHandler(SIGIO, ioHandler); 21710453SAndrew.Bardsley@arm.com} 21810453SAndrew.Bardsley@arm.com 219