/****************************************************************************** * * * Function: fatal_signal_handler * * * * Purpose: handle fatal signals: SIGILL, SIGILL, SIGSEGV, SIGBUS * * * ******************************************************************************/ static void fatal_signal_handler(int sig, siginfo_t *siginfo, void *context) { SIG_CHECK_PARAMS(sig, siginfo, context); zabbix_log(LOG_LEVEL_CRIT, "Got signal [signal:%d(%s),reason:%d,refaddr:%p]. Crashing ...", sig, get_signal_name(sig), SIG_CHECKED_FIELD(siginfo, si_code), SIG_CHECKED_FIELD_TYPE(siginfo, si_addr, void *)); print_fatal_info(sig, siginfo, context); exit(FAIL); }
int zbx_win_exception_filter(unsigned int code, struct _EXCEPTION_POINTERS *ep) { zabbix_log(LOG_LEVEL_CRIT, "Unhandled exception %x detected at 0x%p. Crashing ...", code, ep->ExceptionRecord->ExceptionAddress); print_fatal_info(ep->ContextRecord); print_backtrace(ep->ContextRecord); zabbix_log(LOG_LEVEL_CRIT, "================================"); return EXCEPTION_CONTINUE_SEARCH; }
static void child_signal_handler(int sig, siginfo_t *siginfo, void *context) { if (NULL == siginfo) { zabbix_log(LOG_LEVEL_DEBUG, "received [signal:%d(%s)] with NULL siginfo", sig, get_signal_name(sig)); } if (NULL == context) { zabbix_log(LOG_LEVEL_DEBUG, "received [signal:%d(%s)] with NULL context", sig, get_signal_name(sig)); } switch (sig) { case SIGALRM: zabbix_log(LOG_LEVEL_DEBUG, "timeout while answering request"); break; case SIGILL: case SIGFPE: case SIGSEGV: case SIGBUS: zabbix_log(LOG_LEVEL_CRIT, "Got signal [signal:%d(%s),reason:%d,refaddr:%p]. Crashing ...", sig, get_signal_name(sig), CHECKED_FIELD(siginfo, si_code), CHECKED_FIELD_TYPE(siginfo, si_addr, void *)); print_fatal_info(sig, siginfo, context); exit(FAIL); break; case SIGUSR1: zabbix_log(LOG_LEVEL_DEBUG, "Got signal [signal:%d(%s),sender_pid:%d,sender_uid:%d,value_int:%d].", sig, get_signal_name(sig), CHECKED_FIELD(siginfo, si_pid), CHECKED_FIELD(siginfo, si_uid), CHECKED_FIELD(siginfo, si_value.sival_int)); #ifdef HAVE_SIGQUEUE if (!PARENT_PROCESS) { extern void zbx_sigusr_handler(zbx_task_t task); zbx_sigusr_handler(CHECKED_FIELD(siginfo, si_value.sival_int)); } else if (ZBX_TASK_CONFIG_CACHE_RELOAD == CHECKED_FIELD(siginfo, si_value.sival_int)) { extern unsigned char daemon_type; if (0 != (daemon_type & ZBX_DAEMON_TYPE_PROXY_PASSIVE)) { zabbix_log(LOG_LEVEL_WARNING, "forced reloading of the configuration cache" " cannot be performed for a passive proxy"); } else { union sigval s; extern pid_t *threads; s.sival_int = ZBX_TASK_CONFIG_CACHE_RELOAD; /* threads[0] is configuration syncer (it is set in proxy.c and server.c) */ if (-1 != sigqueue(threads[0], SIGUSR1, s)) { zabbix_log(LOG_LEVEL_DEBUG, "the signal is redirected to" " the configuration syncer"); } else { zabbix_log(LOG_LEVEL_ERR, "failed to redirect signal: %s", zbx_strerror(errno)); } } } #endif break; case SIGQUIT: case SIGINT: case SIGTERM: zabbix_log(parent_pid == CHECKED_FIELD(siginfo, si_pid) ? LOG_LEVEL_DEBUG : LOG_LEVEL_WARNING, "Got signal [signal:%d(%s),sender_pid:%d,sender_uid:%d,reason:%d]. Exiting ...", sig, get_signal_name(sig), CHECKED_FIELD(siginfo, si_pid), CHECKED_FIELD(siginfo, si_uid), CHECKED_FIELD(siginfo, si_code)); if (!PARENT_PROCESS) exit(FAIL); if (0 == exiting) { exiting = 1; zbx_on_exit(); } break; case SIGPIPE: zabbix_log(LOG_LEVEL_DEBUG, "Got signal [signal:%d(%s),sender_pid:%d]. Ignoring ...", sig, get_signal_name(sig), CHECKED_FIELD(siginfo, si_pid)); break; default: zabbix_log(LOG_LEVEL_WARNING, "Got signal [signal:%d(%s),sender_pid:%d,sender_uid:%d]. Ignoring ...", sig, get_signal_name(sig), CHECKED_FIELD(siginfo, si_pid), CHECKED_FIELD(siginfo, si_uid)); } }