diff --git a/src/sim/init_signals.cc b/src/sim/init_signals.cc index b9aa6f6e4d..b574f12ea1 100644 --- a/src/sim/init_signals.cc +++ b/src/sim/init_signals.cc @@ -84,7 +84,8 @@ setupAltStack() static void installSignalHandler(int signal, void (*handler)(int sigtype), - int flags = SA_RESTART) + int flags = SA_RESTART, + struct sigaction *old_sa = NULL) { struct sigaction sa; @@ -93,7 +94,7 @@ installSignalHandler(int signal, void (*handler)(int sigtype), sa.sa_handler = handler; sa.sa_flags = flags; - if (sigaction(signal, &sa, NULL) == -1) + if (sigaction(signal, &sa, old_sa) == -1) panic("Failed to setup handler for signal %i\n", signal); } @@ -196,9 +197,6 @@ initSignals() // Dump intermediate stats and reset them installSignalHandler(SIGUSR2, dumprstStatsHandler); - // Exit cleanly on Interrupt (Ctrl-C) - installSignalHandler(SIGINT, exitNowHandler); - // Print the current cycle number and a backtrace on abort. Make // sure the signal is unmasked and the handler reset when a signal // is delivered to be able to invoke the default handler. @@ -218,4 +216,19 @@ initSignals() installSignalHandler(SIGIO, ioHandler); } +struct sigaction old_int_sa; + +void initSigInt() +{ + // Exit cleanly on Interrupt (Ctrl-C) + installSignalHandler(SIGINT, exitNowHandler, SA_RESTART, &old_int_sa); +} + +void restoreSigInt() +{ + // Restore the old SIGINT handler + sigaction(SIGINT, &old_int_sa, NULL); +} + + } // namespace gem5 diff --git a/src/sim/init_signals.hh b/src/sim/init_signals.hh index ea9f3d5229..2da3aae877 100644 --- a/src/sim/init_signals.hh +++ b/src/sim/init_signals.hh @@ -38,6 +38,10 @@ void exitNowHandler(int sigtype); void abortHandler(int sigtype); void initSignals(); +// separate out sigint handler so that we can restore the python one +void initSigInt(); +void restoreSigInt(); + } // namespace gem5 #endif // __SIM_INIT_SIGNALS_HH__ diff --git a/src/sim/simulate.cc b/src/sim/simulate.cc index abd2b1d391..6505f57904 100644 --- a/src/sim/simulate.cc +++ b/src/sim/simulate.cc @@ -50,6 +50,7 @@ #include "base/types.hh" #include "sim/async.hh" #include "sim/eventq.hh" +#include "sim/init_signals.hh" #include "sim/sim_events.hh" #include "sim/sim_exit.hh" #include "sim/stat_control.hh" @@ -187,6 +188,10 @@ GlobalSimLoopExitEvent *global_exit_event= nullptr; GlobalSimLoopExitEvent * simulate(Tick num_cycles) { + // install the sigint handler to catch ctrl-c and exit the sim loop cleanly + // Note: This should be done before initializing the threads + initSigInt(); + if (global_exit_event)//cleaning last global exit event global_exit_event->clean(); std::unique_ptr quantum_event; @@ -229,6 +234,9 @@ simulate(Tick num_cycles) Event *local_event = doSimLoop(mainEventQueue[0]); assert(local_event); + // Restore normal ctrl-c operation as soon as the event queue is done + restoreSigInt(); + inParallelMode = false; // locate the global exit event and return it to Python