int ap_process_child_status(apr_proc_t *pid, apr_exit_why_e why, int status) { int signum = status; const char *sigdesc = apr_signal_description_get(signum); /* Child died... if it died due to a fatal error, * we should simply bail out. The caller needs to * check for bad rc from us and exit, running any * appropriate cleanups. * * If the child died due to a resource shortage, * the parent should limit the rate of forking */ if (APR_PROC_CHECK_EXIT(why)) { if (status == APEXIT_CHILDSICK) { return status; } if (status == APEXIT_CHILDFATAL) { ap_log_error(APLOG_MARK, APLOG_ALERT, 0, ap_server_conf, "Child %" APR_PID_T_FMT " returned a Fatal error... Apache is exiting!", pid->pid); return APEXIT_CHILDFATAL; } return 0; } if (APR_PROC_CHECK_SIGNALED(why)) { switch (signum) { case SIGTERM: case SIGHUP: case AP_SIG_GRACEFUL: case SIGKILL: break; default: if (APR_PROC_CHECK_CORE_DUMP(why)) { ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, "child pid %ld exit signal %s (%d), " "possible coredump in %s", (long)pid->pid, sigdesc, signum, ap_coredump_dir); } else { ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, ap_server_conf, "child pid %ld exit signal %s (%d)", (long)pid->pid, sigdesc, signum); } } } return 0; }
void default_unix_signal_handler(int signum, siginfo_t *info, void *) { // Unix implementation of synchronous signal handler // This runs in the thread that threw the signal. // We do the somewhat sketchy operation of blocking in here until the error handler // has gracefully stopped the app. if (LLApp::sLogInSignal) { llinfos << "Signal handler - Got signal " << signum << " - " << apr_signal_description_get(signum) << llendl; } switch (signum) { case SIGCHLD: if (LLApp::sLogInSignal) { llinfos << "Signal handler - Got SIGCHLD from " << info->si_pid << llendl; } // Check result code for all child procs for which we've // registered callbacks THIS WILL NOT WORK IF SIGCHLD IS SENT // w/o killing the child (Go, launcher!) // TODO: Now that we're using SIGACTION, we can actually // implement the launcher behavior to determine who sent the // SIGCHLD even if it doesn't result in child termination if (LLApp::sChildMap.count(info->si_pid)) { LLApp::sChildMap[info->si_pid].mGotSigChild = TRUE; } LLApp::incSigChildCount(); return; case SIGABRT: // Abort just results in termination of the app, no funky error handling. if (LLApp::sLogInSignal) { llwarns << "Signal handler - Got SIGABRT, terminating" << llendl; } clear_signals(); raise(signum); return; case SIGINT: case SIGHUP: case SIGTERM: if (LLApp::sLogInSignal) { llwarns << "Signal handler - Got SIGINT, HUP, or TERM, exiting gracefully" << llendl; } // Graceful exit // Just set our state to quitting, not error if (LLApp::isQuitting() || LLApp::isError()) { // We're already trying to die, just ignore this signal if (LLApp::sLogInSignal) { llinfos << "Signal handler - Already trying to quit, ignoring signal!" << llendl; } return; } LLApp::setQuitting(); return; case SIGALRM: case SIGPIPE: case SIGUSR2: default: if (signum == LL_SMACKDOWN_SIGNAL || signum == SIGBUS || signum == SIGILL || signum == SIGFPE || signum == SIGSEGV || signum == SIGQUIT) { if (signum == LL_SMACKDOWN_SIGNAL) { // Smackdown treated just like any other app termination, for now if (LLApp::sLogInSignal) { llwarns << "Signal handler - Handling smackdown signal!" << llendl; } else { // Don't log anything, even errors - this is because this signal could happen anywhere. LLError::setDefaultLevel(LLError::LEVEL_NONE); } // Change the signal that we reraise to SIGABRT, so we generate a core dump. signum = SIGABRT; } if (LLApp::sLogInSignal) { llwarns << "Signal handler - Handling fatal signal!" << llendl; } if (LLApp::isError()) { // Received second fatal signal while handling first, just die right now // Set the signal handlers back to default before handling the signal - this makes the next signal wipe out the app. clear_signals(); if (LLApp::sLogInSignal) { llwarns << "Signal handler - Got another fatal signal while in the error handler, die now!" << llendl; } raise(signum); return; } if (LLApp::sLogInSignal) { llwarns << "Signal handler - Flagging error status and waiting for shutdown" << llendl; } if(LLApp::sDisableCrashlogger) //Don't gracefully handle any signals crash and core for a gdb post mortum { clear_signals(); llwarns << "Fatal signal received, not handling the crash here, passing back to operating system" << llendl; raise(signum); return; } // Flag status to ERROR, so thread_error does its work. LLApp::setError(); // Block in the signal handler until somebody says that we're done. while (LLApp::sErrorThreadRunning && !LLApp::isStopped()) { ms_sleep(10); } if (LLApp::sLogInSignal) { llwarns << "Signal handler - App is stopped, reraising signal" << llendl; } clear_signals(); raise(signum); return; } else { if (LLApp::sLogInSignal) { llinfos << "Signal handler - Unhandled signal " << signum << ", ignoring!" << llendl; } } } }
/* Deprecated */ const char *apr_signal_get_description(int signum) { return apr_signal_description_get(signum); }
void signal_func(int signal) { printf("got signal: %d, %s \n",signal,apr_signal_description_get(signal)); }