void *Test_Thread(void *arg) { bool blocked = *((bool *)arg); const char *name; int sc; sigset_t mask; sigset_t wait_mask; siginfo_t info; if ( blocked ) name = "SignalBlocked"; else name = "SignalNotBlocked"; /* build unblocked mask */ sc = sigemptyset( &mask ); rtems_test_assert( !sc ); printf( "%s - Unblock %s\n", name, signal_name(SIGNAL_ONE) ); sc = sigaddset( &mask, SIGNAL_ONE ); rtems_test_assert( !sc ); if ( !blocked ) { printf( "%s - Unblock %s\n", name, signal_name(SIGNAL_TWO) ); sc = sigaddset( &mask, SIGNAL_TWO ); rtems_test_assert( !sc ); } /* unblocked signals */ sc = pthread_sigmask( SIG_UNBLOCK, &mask, NULL ); rtems_test_assert( !sc ); /* build wait mask */ sc = sigemptyset( &wait_mask ); rtems_test_assert( !sc ); sc = sigaddset( &wait_mask, SIGNAL_ONE ); rtems_test_assert( !sc ); /* wait for a signal */ memset( &info, 0, sizeof(info) ); printf( "%s - Wait for %s unblocked\n", name, signal_name(SIGNAL_ONE) ); sigwaitinfo( &wait_mask, &info ); rtems_test_assert( !sc ); printf( "%s - siginfo.si_signo=%d\n", name, info.si_signo ); printf( "%s - siginfo.si_code=%d\n", name, info.si_code ); /* FIXME: Instead of casting to (uintptr_t) and using PRIxPTR, we * likely should use %p. However, this would render this test's * behavior non-deterministic, because %p's behavior is * "implementation defined" */ printf( "%s - siginfo.si_value=0x%08" PRIxPTR "\n", name, (uintptr_t) info.si_value.sival_ptr ); rtems_test_assert( info.si_signo == SIGNAL_TWO ); rtems_test_assert( info.si_code == SI_USER ); printf( "%s - exiting\n", name ); return NULL; }
/* Given 'status', which is a process status in the form reported by waitpid(2) * and returned by process_status(), returns a string describing how the * process terminated. The caller is responsible for freeing the string when * it is no longer needed. */ char * process_status_msg(int status) { struct ds ds = DS_EMPTY_INITIALIZER; #ifndef _WIN32 if (WIFEXITED(status)) { ds_put_format(&ds, "exit status %d", WEXITSTATUS(status)); } else if (WIFSIGNALED(status)) { char namebuf[SIGNAL_NAME_BUFSIZE]; ds_put_format(&ds, "killed (%s)", signal_name(WTERMSIG(status), namebuf, sizeof namebuf)); } else if (WIFSTOPPED(status)) { char namebuf[SIGNAL_NAME_BUFSIZE]; ds_put_format(&ds, "stopped (%s)", signal_name(WSTOPSIG(status), namebuf, sizeof namebuf)); } else { ds_put_format(&ds, "terminated abnormally (%x)", status); } if (WCOREDUMP(status)) { ds_put_cstr(&ds, ", core dumped"); } #else ds_put_cstr(&ds, "function not supported."); #endif return ds_cstr(&ds); }
/** * If a restart signal is received during exit-notification, reset the * signal and return true. If its a soft restart signal from the event loop * which implies the loop cannot continue, remap to SIGTERM to exit promptly. */ static bool ignore_restart_signals(struct context *c) { bool ret = false; #ifdef ENABLE_OCC if ( (c->sig->signal_received == SIGUSR1 || c->sig->signal_received == SIGHUP) && event_timeout_defined(&c->c2.explicit_exit_notification_interval) ) { if (c->sig->source == SIG_SOURCE_HARD) { msg(M_INFO, "Ignoring %s received during exit notification", signal_name(c->sig->signal_received, true)); signal_reset(c->sig); ret = true; } else { msg(M_INFO, "Converting soft %s received during exit notification to SIGTERM", signal_name(c->sig->signal_received, true)); register_signal(c, SIGTERM, "exit-with-notification"); ret = false; } } #endif return ret; }
void print_signal (const struct signal_info *si, const char *title, int msglevel) { if (si) { const char *hs = (si->hard ? "hard" : "soft"); const char *type = (si->signal_text ? si->signal_text : ""); const char *t = (title ? title : "process"); switch (si->signal_received) { case SIGINT: case SIGTERM: msg (msglevel, "%s[%s,%s] received, %s exiting", signal_name (si->signal_received, true), hs, type, t); break; case SIGHUP: case SIGUSR1: msg (msglevel, "%s[%s,%s] received, %s restarting", signal_name (si->signal_received, true), hs, type, t); break; default: msg (msglevel, "Unknown signal %d [%s,%s] received by %s", si->signal_received, hs, type, t); break; } } else msg (msglevel, "Unknown signal received"); }
void print_signal(const struct signal_info *si, const char *title, int msglevel) { if (si) { const char *type = (si->signal_text ? si->signal_text : ""); const char *t = (title ? title : "process"); const char *hs = NULL; switch (si->source) { case SIG_SOURCE_SOFT: hs = "soft"; break; case SIG_SOURCE_HARD: hs = "hard"; break; case SIG_SOURCE_CONNECTION_FAILED: hs = "connection failed(soft)"; break; default: ASSERT(0); } switch (si->signal_received) { case SIGINT: case SIGTERM: msg(msglevel, "%s[%s,%s] received, %s exiting", signal_name(si->signal_received, true), hs, type, t); break; case SIGHUP: case SIGUSR1: msg(msglevel, "%s[%s,%s] received, %s restarting", signal_name(si->signal_received, true), hs, type, t); break; default: msg(msglevel, "Unknown signal %d [%s,%s] received by %s", si->signal_received, hs, type, t); break; } } else { msg(msglevel, "Unknown signal received"); } }
static void write_context_state(OutputStream * out, Context * ctx) { int fst = 1; assert(!ctx->exited); if (!ctx->intercepted) { write_stringz(out, "0"); write_stringz(out, "null"); write_stringz(out, "null"); return; } /* Number: PC */ json_write_ulong(out, get_regs_PC(ctx->regs)); write_stream(out, 0); /* String: Reason */ json_write_string(out, context_suspend_reason(ctx)); write_stream(out, 0); /* Object: Additional context state info */ write_stream(out, '{'); if (ctx->signal) { json_write_string(out, "Signal"); write_stream(out, ':'); json_write_long(out, ctx->signal); if (signal_name(ctx->signal)) { write_stream(out, ','); json_write_string(out, "SignalName"); write_stream(out, ':'); json_write_string(out, signal_name(ctx->signal)); } fst = 0; } if (ctx->stopped_by_bp && ctx->bp_ids != NULL && ctx->bp_ids[0] != NULL) { int i = 0; if (!fst) write_stream(out, ','); json_write_string(out, "BPs"); write_stream(out, ':'); write_stream(out, '['); while (ctx->bp_ids[i] != NULL) { if (i > 0) write_stream(out, ','); json_write_string(out, ctx->bp_ids[i++]); } write_stream(out, ']'); fst = 0; } write_stream(out, '}'); write_stream(out, 0); }
/* Check whether a fatal signal has occurred and, if so, call the fatal signal * hooks and exit. * * This function is called automatically by poll_block(), but specialized * programs that may not always call poll_block() on a regular basis should * also call it periodically. (Therefore, any function with "block" in its * name should call fatal_signal_run() each time it is called, either directly * or through poll_block(), because such functions can only used by specialized * programs that can afford to block outside their main loop around * poll_block().) */ void fatal_signal_run(void) { sig_atomic_t sig_nr; fatal_signal_init(); sig_nr = stored_sig_nr; if (sig_nr != SIG_ATOMIC_MAX) { char namebuf[SIGNAL_NAME_BUFSIZE]; ovs_mutex_lock(&mutex); VLOG_WARN("terminating with signal %d (%s)", (int)sig_nr, signal_name(sig_nr, namebuf, sizeof namebuf)); call_hooks(sig_nr); /* Re-raise the signal with the default handling so that the program * termination status reflects that we were killed by this signal */ signal(sig_nr, SIG_DFL); raise(sig_nr); ovs_mutex_unlock(&mutex); OVS_NOT_REACHED(); } }
NOEXPORT void client_status(void) { /* dead children detected */ int pid, status; char *sig_name; #ifdef HAVE_WAIT_FOR_PID while((pid=wait_for_pid(-1, &status, WNOHANG))>0) { #else if((pid=wait(&status))>0) { #endif #ifdef WIFSIGNALED if(WIFSIGNALED(status)) { sig_name=signal_name(WTERMSIG(status)); s_log(LOG_DEBUG, "Process %d terminated on %s", pid, sig_name); str_free(sig_name); } else { s_log(LOG_DEBUG, "Process %d finished with code %d", pid, WEXITSTATUS(status)); } } #else s_log(LOG_DEBUG, "Process %d finished with code %d", pid, status); } #endif }
/* * Call management interface with restart info */ void signal_restart_status(const struct signal_info *si) { #ifdef ENABLE_MANAGEMENT if (management) { int state = -1; switch (si->signal_received) { case SIGINT: case SIGTERM: state = OPENVPN_STATE_EXITING; break; case SIGHUP: case SIGUSR1: state = OPENVPN_STATE_RECONNECTING; break; } if (state >= 0) { management_set_state(management, state, si->signal_text ? si->signal_text : signal_name(si->signal_received, true), NULL, NULL, NULL, NULL); } } #endif /* ifdef ENABLE_MANAGEMENT */ }
const char * signal_description (const int signum, const char *sigtext) { if (sigtext) return sigtext; else return signal_name (signum, false); }
static void command_get_signal_list(char * token, Channel * c) { int err = 0; char id[256]; pid_t pid; json_read_string(&c->inp, id, sizeof(id)); if (read_stream(&c->inp) != 0) exception(ERR_JSON_SYNTAX); if (read_stream(&c->inp) != MARKER_EOM) exception(ERR_JSON_SYNTAX); pid = id2pid(id, NULL); write_stringz(&c->out, "R"); write_stringz(&c->out, token); /* pid is ignored, same signal list for all */ write_errno(&c->out, err); if (err) { write_stringz(&c->out, "null"); } else { int i = 0; int n = 0; write_stream(&c->out, '['); for (i = 0; i < 32; i++) { char * name = signal_name(i); char * desc = signal_description(i); if (name != NULL || desc != NULL) { if (n > 0) write_stream(&c->out, ','); write_stream(&c->out, '{'); json_write_string(&c->out, "Index"); write_stream(&c->out, ':'); json_write_long(&c->out, i); if (name != NULL) { write_stream(&c->out, ','); json_write_string(&c->out, "Name"); write_stream(&c->out, ':'); json_write_string(&c->out, name); } if (desc != NULL) { write_stream(&c->out, ','); json_write_string(&c->out, "Description"); write_stream(&c->out, ':'); json_write_string(&c->out, desc); } write_stream(&c->out, ','); json_write_string(&c->out, "Code"); write_stream(&c->out, ':'); json_write_ulong(&c->out, signal_code(i)); write_stream(&c->out, '}'); n++; } } write_stream(&c->out, ']'); write_stream(&c->out, 0); } write_stream(&c->out, MARKER_EOM); }
static void handle_sigTSTP(int signo) { sigset_t all_signals; int error, saved_errno = errno; DEBUG_RANDOM_SLEEP; sigfillset(&all_signals); DPRINTF2(DEBUG_SIGNALS, "got %s, sending it to pgid %d", signal_name(signo), command_pid); zero_select_timeout(); /* Hand the SIGTSTP down to command and its process group */ if (command_pid && (error = kill(-command_pid, SIGTSTP))) { myerror(FATAL|USE_ERRNO, "Failed to deliver SIGTSTP"); } if (within_line_edit) save_rl_state(); mysignal(SIGTSTP, SIG_DFL); /* reset disposition to default (i.e. suspend) */ sigprocmask(SIG_UNBLOCK, &all_signals, NULL); /* respond to sleep- and wake-up signals */ kill(getpid(), SIGTSTP); /* suspend */ /* keyboard gathers dust, kingdoms crumble,.... */ /* .... */ /* Beautiful princess types "fg", (or her father tries to kill us...) and we wake up HERE: */ sigprocmask(SIG_BLOCK, &all_signals, NULL); mysignal(SIGTSTP, &handle_sigTSTP); DPRINTF0(DEBUG_SIGNALS, "woken up"); /* On most systems, command's process group will have been woken up by the handler of the signal that woke us up. This doesn't seem to happen for SIGCONT on QNX, so here goes: */ #ifdef __QNX__ if (command_pid && (error = kill(-command_pid, SIGCONT))) { myerror(FATAL|USE_ERRNO, "Failed to deliver SIGCONT"); } #endif if (within_line_edit) { restore_rl_state(); } else { set_echo(FALSE); cr(); if (skip_rlwrap()) return; move_cursor_to_start_of_prompt(ERASE); cook_prompt_if_necessary(); my_putstr(saved_rl_state.cooked_prompt); } adapt_tty_winsize(STDIN_FILENO, master_pty_fd); /* just in case */ errno = saved_errno; sigprocmask(SIG_UNBLOCK, &all_signals, NULL); }
void suicide_by(int signal, int status) { /* Some signals suggest a program error. When rlwrap kills itself with one of those, the shell may tell the user that rlwrap itself has failed. Make clear that it didn't. @@@ We could also try argv[0] = command_name just before dying ? */ if (signals_program_error(signal)) { myerror(WARNING|NOERRNO, "%s crashed, killed by %s%s.\n%s itself has not crashed, but for transparency,\n" "it will now kill itself %swith the same signal\n", command_name, signal_name(signal), (coredump(status) ? " (core dumped)" : ""), program_name, (coredump(status) ? "" : "(without dumping core) ") ); } uninstall_signal_handlers(); unblock_all_signals(); set_ulimit(RLIMIT_CORE,0); /* prevent our own useless core dump from clobbering the interesting one created by command */ DPRINTF1(DEBUG_SIGNALS, "suicide by signal %s", signal_name(signal)); kill(getpid(), signal); /* still alive? */ sleep(1); exit(0); }
// This function handles deadly signals. // It tries to preserve any swap files and exit properly. // (partly from Elvis). // NOTE: Avoid unsafe functions, such as allocating memory, they can result in // a deadlock. static void deadly_signal(int signum) { // Set the v:dying variable. set_vim_var_nr(VV_DYING, 1); snprintf((char *)IObuff, sizeof(IObuff), "Vim: Caught deadly signal '%s'\n", signal_name(signum)); // Preserve files and exit. preserve_exit(); }
// This function handles deadly signals. // It tries to preserve any swap files and exit properly. // (partly from Elvis). // NOTE: Avoid unsafe functions, such as allocating memory, they can result in // a deadlock. static void deadly_signal(int signum) { // Set the v:dying variable. set_vim_var_nr(VV_DYING, 1); sprintf((char *)IObuff, "Vim: Caught deadly signal '%s'\n", signal_name(signum)); // Preserve files and exit. This sets the really_exiting flag to prevent // calling free(). preserve_exit(); }
/* * If the given signal is still in its default state, set it to the given * handler. */ static int CatchIfDefault(int sig, RETSIGTYPE (*handler) (int)) { int result; #if HAVE_SIGACTION || HAVE_SIGVEC sigaction_t old_act; sigaction_t new_act; memset(&new_act, 0, sizeof(new_act)); sigemptyset(&new_act.sa_mask); #ifdef SA_RESTART #ifdef SIGWINCH if (sig != SIGWINCH) #endif new_act.sa_flags |= SA_RESTART; #endif /* SA_RESTART */ new_act.sa_handler = handler; if (sigaction(sig, NULL, &old_act) == 0 && (old_act.sa_handler == SIG_DFL || old_act.sa_handler == handler #if USE_SIGWINCH || (sig == SIGWINCH && old_act.sa_handler == SIG_IGN) #endif )) { (void) sigaction(sig, &new_act, NULL); result = TRUE; } else { result = FALSE; } #else /* !HAVE_SIGACTION */ RETSIGTYPE (*ohandler) (int); ohandler = signal(sig, SIG_IGN); if (ohandler == SIG_DFL || ohandler == handler #if USE_SIGWINCH || (sig == SIGWINCH && ohandler == SIG_IGN) #endif ) { signal(sig, handler); result = TRUE; } else { signal(sig, ohandler); result = FALSE; } #endif T(("CatchIfDefault - will %scatch %s", result ? "" : "not ", signal_name(sig))); return result; }
static void handle_program_error_signal(int sig) { /* Even after sudden and unexpected death, leave the terminal in a tidy state */ int res; printf("\n%s: Oops, crashed (caught %s) - this should not have happened!\n" "If you need a core dump, re-configure with --enable-debug and rebuild\n" "Resetting terminal and cleaning up...\n", program_name, signal_name(sig)); if (colour_the_prompt || filter_pid) res = write(STDOUT_FILENO,"\033[0m",4); /* reset terminal colours */ if (terminal_settings_saved) tcsetattr(STDIN_FILENO, TCSAFLUSH, &saved_terminal_settings); exit(EXIT_FAILURE); }
void mysignal(int sig, sighandler_type handler) { #ifdef HAVE_SIGACTION struct sigaction action; DPRINTF3(DEBUG_SIGNALS,"Setting handler for signal %d (%s) to <0x%lx>", sig, signal_name(sig), (long) handler); action.sa_handler = handler; sigfillset(&action.sa_mask); /* don't bother making our signal handlers re-entrant (they aren't) */ action.sa_flags = (sig == SIGCHLD ? SA_NOCLDSTOP : 0); /* no SA_RESTART */ if (sigaction(sig, &action, NULL) != 0) # else /* rlwrap running in Ye Olde Computer Museum?? */ if (signal(sig, handler) == SIG_ERR) # endif if(handler != SIG_DFL) /* allow e.g. KILL to be set to its default */ myerror(FATAL|USE_ERRNO, "Failed setting handler for signal %d (%s)", sig, signal_name(sig)); }
v8::Handle<v8::Value> GetSignalDescriptionByClass(const v8::Arguments& args) { v8::HandleScope scope; if (args.Length() != 2) { ThrowException(v8::Exception::TypeError(v8::String::New("Wrong number of arguments"))); return scope.Close(v8::Undefined()); } if (!args[0]->IsString() || !args[1]->IsString()) { ThrowException(v8::Exception::TypeError(v8::String::New("Wrong arguments"))); return scope.Close(v8::Undefined()); } v8::String::AsciiValue class_name(args[0]->ToString()); v8::String::AsciiValue signal_name(args[1]->ToString()); v8::Handle<v8::String> res = v8::String::New(switcher_container[0]->get_signal_description_by_class(std::string(*class_name), std::string(*signal_name)).c_str()); return scope.Close(res); }
v8::Handle<v8::Value> UnsubscribeToSignal(const v8::Arguments& args) { v8::HandleScope scope; if (args.Length() != 2) { ThrowException(v8::Exception::TypeError(v8::String::New("Wrong number of arguments"))); return scope.Close(v8::Undefined()); } if (!args[0]->IsString() || !args[1]->IsString()) { ThrowException(v8::Exception::TypeError(v8::String::New("Wrong arguments"))); return scope.Close(v8::Undefined()); } v8::String::AsciiValue element_name(args[0]->ToString()); v8::String::AsciiValue signal_name(args[1]->ToString()); v8::Handle<v8::Boolean> res = v8::Boolean::New(switcher_container[0]->unsubscribe_signal (std::string ("signal_sub"), std::string(*element_name), std::string(*signal_name))); return scope.Close(res); }
/* Check whether a fatal signal has occurred and, if so, call the fatal signal * hooks and exit. * * This function is called automatically by poll_block(), but specialized * programs that may not always call poll_block() on a regular basis should * also call it periodically. (Therefore, any function with "block" in its * name should call fatal_signal_run() each time it is called, either directly * or through poll_block(), because such functions can only used by specialized * programs that can afford to block outside their main loop around * poll_block().) */ void fatal_signal_run(void) { sig_atomic_t sig_nr; fatal_signal_init(); sig_nr = stored_sig_nr; if (sig_nr != SIG_ATOMIC_MAX) { VLOG_WARN("terminating with signal %d (%s)", (int)sig_nr, signal_name(sig_nr)); call_hooks(sig_nr); /* Re-raise the signal with the default handling so that the program * termination status reflects that we were killed by this signal */ signal(sig_nr, SIG_DFL); raise(sig_nr); } }
/** * @brief Handle signals that indicate the program was killed because of an invalid operation (including SIGSEGV). * @note The signals handled by this function are: SIGSEGV, SIGFPE, SIGBUS, SIGSYS, and SIGABRT. * The handler will respond by logging a stack backtrace, and terminating the program with abort(). * @param signal the number of the signal that was received. * @return This function returns no value. */ void signal_segfault(int signal) { char signame[32]; struct sigaction clear; // Log it. log_options(M_LOG_CRITICAL | M_LOG_STACK_TRACE, "Memory corruption has been detected. Attempting to print a back trace and exit. { signal = %s }", signal_name(signal, signame, 32)); // Configure the structure to return a signal to its default handler via the sigaction call below. mm_wipe(&clear, sizeof(struct sigaction)); sigemptyset(&clear.sa_mask); clear.sa_handler = SIG_DFL; clear.sa_flags = 0; // Return the SIGABRT handler to its default value. This allows us to call abort and trigger a core dump without creating a recursive loop. sigaction(SIGABRT, &clear, NULL); // The abort function should trigger the creation of a core dump file if core dumps have been enabled. abort(); }
static void pass_on_signal(int signo) { int ret, saved_errno = errno, pass_it_on = TRUE; DEBUG_RANDOM_SLEEP; zero_select_timeout(); #ifdef DEBUG log_named_signal(signo); #endif if(pass_on_sigINT_as_sigTERM && signo == SIGINT) signo=SIGTERM; switch (signo) { case SIGWINCH: /* non-POSIX, but present on most systems */ /* Make slave pty's winsize equal to that of STDIN. Pass the signal on *only if* winsize has changed. This is particularly important because we have the slave pty still open - when we pass on the signal the child will probably do a TIOCSWINSZ ioctl() on the slave pty - causing us (the parent) to get a SIGWINCH again, thus getting stuck in a loop */ pass_it_on = adapt_tty_winsize(STDIN_FILENO, master_pty_fd); break; case SIGTERM: sigterm_received = TRUE; break; default: break; } if (!command_pid) pass_it_on = FALSE; /* no child (yet) to pass it on to */ if (pass_it_on) { /* we resend the signal to the process *group* of the child */ ret = kill( -command_pid, signo); DPRINTF3(DEBUG_SIGNALS, "kill(%d,%s) = %d", -command_pid, signal_name(signo), ret); we_just_got_a_signal_or_EOF = TRUE; /* signal to main loop that next command output should leave the prompt alone */ } errno = saved_errno; }
NOEXPORT int signal_pipe_dispatch(void) { static int sig; static size_t ptr=0; ssize_t num; char *sig_name; s_log(LOG_DEBUG, "Dispatching signals from the signal pipe"); for(;;) { num=readsocket(signal_pipe[0], (char *)&sig+ptr, sizeof sig-ptr); if(num==-1 && get_last_socket_error()==S_EWOULDBLOCK) { s_log(LOG_DEBUG, "Signal pipe is empty"); return 0; } if(num==-1 || num==0) { if(num) sockerror("signal pipe read"); else s_log(LOG_ERR, "Signal pipe closed"); s_poll_remove(fds, signal_pipe[0]); closesocket(signal_pipe[0]); closesocket(signal_pipe[1]); if(signal_pipe_init()) { s_log(LOG_ERR, "Signal pipe reinitialization failed; terminating"); return 1; } s_poll_add(fds, signal_pipe[0], 1, 0); s_log(LOG_ERR, "Signal pipe reinitialized"); return 0; } ptr+=(size_t)num; if(ptr<sizeof sig) { s_log(LOG_DEBUG, "Incomplete signal pipe read (ptr=%ld)", (long)ptr); return 0; } ptr=0; switch(sig) { #ifndef USE_WIN32 case SIGCHLD: s_log(LOG_DEBUG, "Processing SIGCHLD"); #ifdef USE_FORK client_status(); /* report status of client process */ #else /* USE_UCONTEXT || USE_PTHREAD */ child_status(); /* report status of libwrap or 'exec' process */ #endif /* defined USE_FORK */ break; #endif /* !defind USE_WIN32 */ case SIGNAL_RELOAD_CONFIG: s_log(LOG_DEBUG, "Processing SIGNAL_RELOAD_CONFIG"); if(options_parse(CONF_RELOAD)) { s_log(LOG_ERR, "Failed to reload the configuration file"); } else { unbind_ports(); log_close(); options_apply(); log_open(); ui_config_reloaded(); if(bind_ports()) { /* FIXME: handle the error */ } } break; case SIGNAL_REOPEN_LOG: s_log(LOG_DEBUG, "Processing SIGNAL_REOPEN_LOG"); log_close(); log_open(); s_log(LOG_NOTICE, "Log file reopened"); break; case SIGNAL_TERMINATE: s_log(LOG_DEBUG, "Processing SIGNAL_TERMINATE"); s_log(LOG_NOTICE, "Terminated"); return 1; default: sig_name=signal_name(sig); s_log(LOG_ERR, "Received %s; terminating", sig_name); str_free(sig_name); return 1; } } }
/* * Entry pointer for signal handlers */ static void CppcheckSignalHandler(int signo, siginfo_t * info, void * /*context*/) { const char * const signame = signal_name(signo); const char * const sigtext = strsignal(signo); bool bPrintCallstack=true; FILE* f=CppCheckExecutor::getExceptionOutput()=="stderr" ? stderr : stdout; fputs("Internal error: cppcheck received signal ", f); fputs(signame, f); fputs(", ", f); fputs(sigtext, f); switch (signo) { case SIGBUS: switch (info->si_code) { case BUS_ADRALN: // invalid address alignment fprintf(f, " - BUS_ADRALN"); break; case BUS_ADRERR: // nonexistent physical address fprintf(f, " - BUS_ADRERR"); break; case BUS_OBJERR: // object-specific hardware error fprintf(f, " - BUS_OBJERR"); break; #ifdef BUS_MCEERR_AR case BUS_MCEERR_AR: // Hardware memory error consumed on a machine check; fprintf(f, " - BUS_MCEERR_AR"); break; #endif #ifdef BUS_MCEERR_AO case BUS_MCEERR_AO: // Hardware memory error detected in process but not consumed fprintf(f, " - BUS_MCEERR_AO"); break; #endif default: break; } fprintf(f, " (at 0x%p).\n", info->si_addr); break; case SIGFPE: switch (info->si_code) { case FPE_INTDIV: // integer divide by zero fprintf(f, " - FPE_INTDIV"); break; case FPE_INTOVF: // integer overflow fprintf(f, " - FPE_INTOVF"); break; case FPE_FLTDIV: // floating-point divide by zero fprintf(f, " - FPE_FLTDIV"); break; case FPE_FLTOVF: // floating-point overflow fprintf(f, " - FPE_FLTOVF"); break; case FPE_FLTUND: // floating-point underflow fprintf(f, " - FPE_FLTUND"); break; case FPE_FLTRES: // floating-point inexact result fprintf(f, " - FPE_FLTRES"); break; case FPE_FLTINV: // floating-point invalid operation fprintf(f, " - FPE_FLTINV"); break; case FPE_FLTSUB: // subscript out of range fprintf(f, " - FPE_FLTSUB"); break; default: break; } fprintf(f, " (at 0x%p).\n", info->si_addr); break; case SIGILL: switch (info->si_code) { case ILL_ILLOPC: // illegal opcode fprintf(f, " - ILL_ILLOPC"); break; case ILL_ILLOPN: // illegal operand fprintf(f, " - ILL_ILLOPN"); break; case ILL_ILLADR: // illegal addressing mode fprintf(f, " - ILL_ILLADR"); break; case ILL_ILLTRP: // illegal trap fprintf(f, " - ILL_ILLTRP"); break; case ILL_PRVOPC: // privileged opcode fprintf(f, " - ILL_PRVOPC"); break; case ILL_PRVREG: // privileged register fprintf(f, " - ILL_PRVREG"); break; case ILL_COPROC: // coprocessor error fprintf(f, " - ILL_COPROC"); break; case ILL_BADSTK: // internal stack error fprintf(f, " - ILL_BADSTK"); break; default: break; } fprintf(f, " (at 0x%p).\n", info->si_addr); break; case SIGINT: bPrintCallstack=false; fprintf(f, ".\n"); break; case SIGSEGV: switch (info->si_code) { case SEGV_MAPERR: // address not mapped to object fprintf(f, " - SEGV_MAPERR"); break; case SEGV_ACCERR: // invalid permissions for mapped object fprintf(f, " - SEGV_ACCERR"); break; default: break; } fprintf(f, " (at 0x%p).\n", info->si_addr); break; default: fputs(".\n", f); break; } if (bPrintCallstack) { print_stacktrace(f, true); fputs("\nPlease report this to the cppcheck developers!\n", f); } abort(); }
* @note This function handles the following signals: SIGINT, SIGQUIT, and SIGTERM. * The shutdown procedure is as follows: * 1. Set status to -1 and sleep for .1 second to allow for normal daemon termination. * 2. Signal all worker threads to wake up blocked threads, and sleep one more second. * 3. Loop through all possible file descriptors and if the descriptor matches a socket that is bound to a magma server, close it. * * @param signal the number of the signal delivered to the process. * @return This function returns no value. */ void signal_shutdown(int signal) { pthread_t status_thread; const struct timespec split = { .tv_sec = 0, .tv_nsec = 100000000 }, single = { .tv_sec = 1, .tv_nsec = 0 }; // We assume the server is being shutdown for a good reason. log_critical("Signal received. The Magma daemon is attempting a graceful exit. { signal = %s }", signal_name(signal, MEMORYBUF(32), 32)); // Clear the thread structure or we'll get a segfault when we attempt the thread join operation. mm_wipe(&status_thread, sizeof(pthread_t)); // Set the status flag so all the worker threads exit nicely. thread_launch(&status_thread, &status_signal, NULL); // We give threads 0.1 seconds to ensure the status update is queued and awaiting the lock. nanosleep(&split, NULL); // Signals the worker threads, so they unblock one more time and see the updated status, thus exiting normally. queue_signal(); // Then sleep for one second before forcibly shutting down the client connections. nanosleep(&single, NULL);
/* * Entry pointer for signal handlers * It uses functions which are not safe to be called from a signal handler, * but when ending up here something went terribly wrong anyway. * And all which is left is just printing some information and terminate. */ static void CppcheckSignalHandler(int signo, siginfo_t * info, void * context) { int type = -1; pid_t killid = getpid(); const ucontext_t* uc = reinterpret_cast<const ucontext_t*>(context); #ifdef __linux__ killid = (pid_t) syscall(SYS_gettid); if (uc) { type = (int)uc->uc_mcontext.gregs[REG_ERR] & 2; } #endif const char * const signame = signal_name(signo); const char * const sigtext = strsignal(signo); bool bPrintCallstack=true; FILE* f=CppCheckExecutor::getExceptionOutput()=="stderr" ? stderr : stdout; fputs("Internal error: cppcheck received signal ", f); fputs(signame, f); fputs(", ", f); fputs(sigtext, f); switch (signo) { case SIGBUS: switch (info->si_code) { case BUS_ADRALN: // invalid address alignment fputs(" - BUS_ADRALN", f); break; case BUS_ADRERR: // nonexistent physical address fputs(" - BUS_ADRERR", f); break; case BUS_OBJERR: // object-specific hardware error fputs(" - BUS_OBJERR", f); break; #ifdef BUS_MCEERR_AR case BUS_MCEERR_AR: // Hardware memory error consumed on a machine check; fputs(" - BUS_MCEERR_AR", f); break; #endif #ifdef BUS_MCEERR_AO case BUS_MCEERR_AO: // Hardware memory error detected in process but not consumed fputs(" - BUS_MCEERR_AO", f); break; #endif default: break; } fprintf(f, " (at 0x%p).\n", info->si_addr); break; case SIGFPE: switch (info->si_code) { case FPE_INTDIV: // integer divide by zero fputs(" - FPE_INTDIV", f); break; case FPE_INTOVF: // integer overflow fputs(" - FPE_INTOVF", f); break; case FPE_FLTDIV: // floating-point divide by zero fputs(" - FPE_FLTDIV", f); break; case FPE_FLTOVF: // floating-point overflow fputs(" - FPE_FLTOVF", f); break; case FPE_FLTUND: // floating-point underflow fputs(" - FPE_FLTUND", f); break; case FPE_FLTRES: // floating-point inexact result fputs(" - FPE_FLTRES", f); break; case FPE_FLTINV: // floating-point invalid operation fputs(" - FPE_FLTINV", f); break; case FPE_FLTSUB: // subscript out of range fputs(" - FPE_FLTSUB", f); break; default: break; } fprintf(f, " (at 0x%p).\n", info->si_addr); break; case SIGILL: switch (info->si_code) { case ILL_ILLOPC: // illegal opcode fputs(" - ILL_ILLOPC", f); break; case ILL_ILLOPN: // illegal operand fputs(" - ILL_ILLOPN", f); break; case ILL_ILLADR: // illegal addressing mode fputs(" - ILL_ILLADR", f); break; case ILL_ILLTRP: // illegal trap fputs(" - ILL_ILLTRP", f); break; case ILL_PRVOPC: // privileged opcode fputs(" - ILL_PRVOPC", f); break; case ILL_PRVREG: // privileged register fputs(" - ILL_PRVREG", f); break; case ILL_COPROC: // coprocessor error fputs(" - ILL_COPROC", f); break; case ILL_BADSTK: // internal stack error fputs(" - ILL_BADSTK", f); break; default: break; } fprintf(f, " (at 0x%p).\n", info->si_addr); break; case SIGINT: bPrintCallstack=false; fputs(".\n", f); break; case SIGSEGV: switch (info->si_code) { case SEGV_MAPERR: // address not mapped to object fputs(" - SEGV_MAPERR", f); break; case SEGV_ACCERR: // invalid permissions for mapped object fputs(" - SEGV_ACCERR", f); break; default: break; } fprintf(f, " (%sat 0x%p).\n", (type==-1)? "" : (type==0) ? "reading " : "writing ", info->si_addr); break; default: fputs(".\n", f); break; } if (bPrintCallstack) { print_stacktrace(f, true); fputs("\nPlease report this to the cppcheck developers!\n", f); } // now let the system proceed, shutdown and hopefully dump core for post-mortem analysis signal(signo, SIG_DFL); kill(killid, signo); }
void *POSIX_Init( void *argument ) { int sc; pthread_t id; struct sigaction act; bool trueArg = true; bool falseArg = false; struct timespec delay_request; puts( "\n\n*** POSIX TEST SIGNAL " TEST_NAME " ***" ); puts( "Init - Variation is: " TEST_STRING ); Signal_occurred = false; act.sa_handler = NULL; act.sa_sigaction = Signal_handler; act.sa_flags = SA_SIGINFO; sigaction( SIGNAL_ONE, &act, NULL ); sigaction( SIGNAL_TWO, &act, NULL ); /* create threads */ sc = pthread_create( &id, NULL, Test_Thread, &falseArg ); rtems_test_assert( !sc ); sc = pthread_create( &id, NULL, Test_Thread, &trueArg ); rtems_test_assert( !sc ); puts( "Init - sleep - let threads settle - OK" ); delay_request.tv_sec = 0; delay_request.tv_nsec = 5 * 100000000; sc = nanosleep( &delay_request, NULL ); rtems_test_assert( !sc ); puts( "Init - sleep - SignalBlocked thread settle - OK" ); sc = nanosleep( &delay_request, NULL ); rtems_test_assert( !sc ); printf( "Init - sending %s - deliver to one thread\n", signal_name(SIGNAL_TWO)); sc = SEND_SIGNAL( SIGNAL_TWO ); rtems_test_assert( !sc ); printf( "Init - sending %s - deliver to other thread\n", signal_name(SIGNAL_TWO)); sc = SEND_SIGNAL( SIGNAL_TWO ); rtems_test_assert( !sc ); #if defined(TO_PROCESS) printf( "Init - sending %s - expect EAGAIN\n", signal_name(SIGNAL_TWO) ); sc = SEND_SIGNAL( SIGNAL_TWO ); rtems_test_assert( sc == -1 ); rtems_test_assert( errno == EAGAIN ); #endif puts( "Init - sleep - let thread report if it unblocked - OK" ); usleep(500000); /* we are just sigwait'ing the signal, not delivering it */ rtems_test_assert( Signal_occurred == true ); puts( "*** END OF POSIX TEST SIGNAL " TEST_NAME " ***" ); rtems_test_exit(0); return NULL; /* just so the compiler thinks we returned something */ }
static void log_named_signal(int signo) { if (debug) DPRINTF1(DEBUG_SIGNALS, "got %s", signal_name(signo)); }
* The string is probably a (possibly multi-word) description of the signal * (e.g. "Hangup") instead of just the stringified version of the macro * (e.g. "SIGHUP"). */ const char * signal_name(int signum, char *namebuf, size_t bufsize) { #if HAVE_DECL_SYS_SIGLIST if (signum >= 0 && signum < N_SIGNALS) { const char *name = sys_siglist[signum]; if (name) { return name; } } #endif snprintf(namebuf, bufsize, "signal %d", signum); return namebuf; } void xsigaction(int signum, const struct sigaction *new, struct sigaction *old) { if (sigaction(signum, new, old)) { char namebuf[SIGNAL_NAME_BUFSIZE]; VLOG_FATAL("sigaction(%s) failed (%s)", signal_name(signum, namebuf, sizeof namebuf), ovs_strerror(errno)); } }