void DebugLoop(const TargetInfo& ti) { while (true) { // Wait for the child to exit or generate a signal requiring our attention int status; if (waitpid(ti.m_pid, &status, 0) == -1) { assert(!"waitpid() failed"); break; } // Handle signal if (WIFEXITED(status)) { std::printf("ghd: Child done (%i), exiting\n", WEXITSTATUS(status)); break; } else if (WIFSIGNALED(status)) { std::printf("ghd: Child terminated (%s), exiting\n", SignalToString(WTERMSIG(status))); break; } else if (WIFSTOPPED(status)) { // Child has stopped, forwarding us some a signal. Stack trace on fault or continue const int sig = WSTOPSIG(status); switch (sig) { // Fault? case SIGSEGV: case SIGBUS: case SIGILL: case SIGFPE: case SIGSYS: std::printf("ghd: Child stopped on fault '%s'\n", SignalToString(sig)); TraceProcessState(ti); return; case SIGALRM: // Just ignore this one silently PTraceContinue(ti.m_pid); break; // Continue default: std::printf( "ghd: Received signal '%s' from child, continuing\n", SignalToString(sig)); PTraceContinue(ti.m_pid); break; } } else std::printf("ghd: Unknown event from child\n"); } }
/******************************************************************** * Pass on selected signals to the slave process. *******************************************************************/ static void SignalPassOn(int nSignal) { Feedback fb(sSlaveId + " signal handler"); if (child_pid != 0) { fb.Info(1) << "Received signal " << nSignal << " (" << SignalToString(nSignal) << "). Passing it on to slave with pid " << child_pid << "."; kill(child_pid, nSignal); } else fb.Info(1) << "Received signal " << nSignal << " (" << SignalToString(nSignal) << "), but child pid is 0, so it cannot be passed on."; }
/* ================= Sys_SigHandler ================= */ void Sys_SigHandler( int signal ) { static qboolean signalcaught = qfalse; if( signalcaught ) { VM_Forced_Unload_Start(); Com_Printf("DOUBLE SIGNAL FAULT: Received signal %d: \"%s\", exiting...\n", signal, SignalToString(signal)); exit(1); } else { signalcaught = qtrue; #ifndef DEDICATED CL_Shutdown( ); #endif SV_Shutdown( va( "Received signal %d", signal ) ); VM_Forced_Unload_Done(); } if( signal == SIGTERM || signal == SIGINT ) { Sys_Exit( 1 ); } else { Sys_Exit( 2 ); } }