X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fsig-monitor.c;h=e15c32deb696d7746b53112f0fef813b2ffba94d;hb=5dd7df31306b95a3fafe6d3238d4553107a6c70f;hp=db833437398a72667a75ea6535b972f8e7781b6e;hpb=1e9c33f9a853aa7b5e89b32fecf54835a04b41ba;p=src%2Fapp-framework-binder.git diff --git a/src/sig-monitor.c b/src/sig-monitor.c index db833437..e15c32de 100644 --- a/src/sig-monitor.c +++ b/src/sig-monitor.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 "IoT.bzh" + * Copyright (C) 2017, 2018 "IoT.bzh" * Author José Bollo * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -40,6 +40,11 @@ static _Thread_local int in_safe_dumpstack; static _Thread_local int thread_timer_set; static _Thread_local timer_t thread_timerid; +/* internal signal lists */ +static int sigerr[] = { SIG_FOR_TIMER, SIGSEGV, SIGFPE, SIGILL, SIGBUS, 0 }; +static int sigterm[] = { SIGINT, SIGABRT, SIGTERM, 0 }; +static int exiting = 0; + /* * Dumps the current stack */ @@ -161,6 +166,44 @@ static inline void timeout_delete() } } +/* install the handlers */ +static int install(void (*handler)(int), int *signals) +{ + int result = 1; + struct sigaction sa; + + sa.sa_handler = handler; + sigemptyset(&sa.sa_mask); + sa.sa_flags = SA_NODEFER; + while(*signals > 0) { + if (sigaction(*signals, &sa, NULL) < 0) { + ERROR("failed to install signal handler for signal %s: %m", strsignal(*signals)); + result = 0; + } + signals++; + } + return result; +} + +/* + * rescue exit + */ +static void on_rescue_exit(int signum) +{ + ERROR("Rescue exit for signal %d: %s", signum, strsignal(signum)); + _exit(exiting); +} + +/* + * Do a safe exit + */ +static void safe_exit(int code) +{ + install(on_rescue_exit, sigerr); + install(on_rescue_exit, sigterm); + exiting = code; + exit(code); +} /* Handles signals that terminate the process */ static void on_signal_terminate (int signum) @@ -170,7 +213,7 @@ static void on_signal_terminate (int signum) if (signum == SIGABRT) safe_dumpstack(3, signum); } - exit(1); + safe_exit(1); } /* Handles monitored signals that can be continued */ @@ -190,33 +233,11 @@ static void on_signal_error(int signum) longjmp(*error_handler, signum); ERROR("Unmonitored signal %d received: %s", signum, strsignal(signum)); - exit(2); -} - -/* install the handlers */ -static int install(void (*handler)(int), int *signals) -{ - int result = 1; - struct sigaction sa; - - sa.sa_handler = handler; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_NODEFER; - while(*signals > 0) { - if (sigaction(*signals, &sa, NULL) < 0) { - ERROR("failed to install signal handler for signal %s: %m", strsignal(*signals)); - result = 0; - } - signals++; - } - return result; + safe_exit(2); } int sig_monitor_init() { - static int sigerr[] = { SIG_FOR_TIMER, SIGSEGV, SIGFPE, SIGILL, SIGBUS, 0 }; - static int sigterm[] = { SIGINT, SIGABRT, SIGTERM, 0 }; - return (install(on_signal_error, sigerr) & install(on_signal_terminate, sigterm)) - 1; }