2 * Copyright 2013 Samsung Electronics Co., Ltd
4 * Licensed under the Flora License, Version 1.1 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://floralicense.org/license/
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
24 #include <sys/types.h>
35 #include <widget_errno.h>
36 #include <widget_provider.h>
37 #include <widget_conf.h>
39 #include "critical_log.h"
48 #if defined(_USE_ECORE_TIME_GET)
51 struct timeval alarm_tv;
55 struct sigaction SEGV_act;
56 struct sigaction ILL_act;
57 struct sigaction ALRM_act;
58 struct sigaction USR1_act;
59 struct sigaction ABRT_act;
67 static void signal_handler(int signum, siginfo_t *info, void *unused)
72 so_fname = util_get_current_module(&symbol);
74 if (info->si_signo == SIGALRM) {
76 DbgPrint("Ignore false alarm signal [false]\n");
80 #if defined(_USE_ECORE_TIME_GET)
82 tv = ecore_time_get();
83 if (tv - s_info.alarm_tv < DEFAULT_LIFE_TIMER) {
84 DbgPrint("Ignore false alarm signal [%lf]\n", tv - s_info.alarm_tv);
88 CRITICAL_LOG("ALARM: %lf (%d, %d)\n", tv - s_info.alarm_tv, DEFAULT_LIFE_TIMER, DEFAULT_LOAD_TIMER);
91 struct timeval res_tv;
93 if (gettimeofday(&tv, NULL) < 0) {
94 ErrPrint("gettimeofday: %d\n", errno);
99 timersub(&tv, &s_info.alarm_tv, &res_tv);
105 if (res_tv.tv_sec < DEFAULT_LIFE_TIMER) {
106 DbgPrint("Ignore false alarm signal [%d]\n", res_tv.tv_sec);
110 CRITICAL_LOG("ALARM: %d.%d (%d, %d)\n",
111 res_tv.tv_sec, res_tv.tv_usec, DEFAULT_LIFE_TIMER, DEFAULT_LOAD_TIMER);
113 } else if (so_fname) {
117 snprintf(log_fname, sizeof(log_fname), "%s/slave.%d", WIDGET_CONF_LOG_PATH, getpid());
118 fd = open(log_fname, O_WRONLY|O_CREAT|O_SYNC, 0644);
120 if (write(fd, so_fname, strlen(so_fname)) != strlen(so_fname)) {
121 ErrPrint("Failed to recording the fault SO filename (%s)\n", so_fname);
124 ErrPrint("close: %d\n", errno);
129 CRITICAL_LOG("SIGNAL> Received from PID[%d]\n", info->si_pid);
130 CRITICAL_LOG("SIGNAL> Signal: %d (%d)\n", signum, info->si_signo);
131 CRITICAL_LOG("SIGNAL> Error code: %d\n", info->si_code);
132 CRITICAL_LOG("SIGNAL> Address: %p\n", info->si_addr);
133 CRITICAL_LOG("Package: [%s] Symbol[%s]\n", so_fname, symbol);
136 int len = strlen(s_info.argv[0]);
137 memset(s_info.argv[0], 0, len);
138 strncpy(s_info.argv[0], util_basename(so_fname), len - 1);
141 CRITICAL_LOG("Unable to find a so_fname (%s)\n", symbol);
148 s_info.SEGV_act.sa_sigaction(signum, info, unused);
151 s_info.ALRM_act.sa_sigaction(signum, info, unused);
154 s_info.ABRT_act.sa_sigaction(signum, info, unused);
157 s_info.ILL_act.sa_sigaction(signum, info, unused);
160 s_info.USR1_act.sa_sigaction(signum, info, unused);
163 ErrPrint("Unhandled signal\n");
168 HAPI int fault_init(char **argv)
170 struct sigaction act;
175 act.sa_sigaction = signal_handler;
176 act.sa_flags = SA_SIGINFO;
178 if (sigemptyset(&act.sa_mask) != 0) {
179 ErrPrint("Failed to init signal: %d\n", errno);
182 if (sigaddset(&act.sa_mask, SIGUSR1) != 0) {
183 ErrPrint("Failed to add set: %d\n", errno);
186 if (sigaddset(&act.sa_mask, SIGALRM) != 0) {
187 ErrPrint("Failed to add set: %d\n", errno);
190 ecore_abort = getenv("ECORE_ERROR_ABORT");
191 if (!ecore_abort || ecore_abort[0] != '1') {
192 if (sigaddset(&act.sa_mask, SIGSEGV) != 0) {
193 ErrPrint("Failed to add set: %d\n", errno);
195 if (sigaddset(&act.sa_mask, SIGABRT) != 0) {
196 ErrPrint("Failed to add set: %d\n", errno);
198 if (sigaddset(&act.sa_mask, SIGILL) != 0) {
199 ErrPrint("Failed to add set: %d\n", errno);
202 if (sigaction(SIGSEGV, &act, &s_info.SEGV_act) < 0) {
203 ErrPrint("Failed to install the SEGV handler\n");
206 if (sigaction(SIGABRT, &act, &s_info.ABRT_act) < 0) {
207 ErrPrint("Faield to install the ABRT handler\n");
210 if (sigaction(SIGILL, &act, &s_info.ILL_act) < 0) {
211 ErrPrint("Faield to install the ILL handler\n");
215 if (sigaction(SIGUSR1, &act, &s_info.USR1_act) < 0) {
216 ErrPrint("Failed to install the USR1 handler\n");
219 if (sigaction(SIGALRM, &act, &s_info.ALRM_act) < 0) {
220 ErrPrint("Failed to install the ALRM handler\n");
226 HAPI int fault_fini(void)
230 * remove all signal handlers
235 HAPI int fault_mark_call(const char *pkgname, const char *filename, const char *funcname, int noalarm, int life_time)
237 if (!s_info.disable_checker) {
238 widget_provider_send_call(pkgname, filename, funcname);
242 * To use this "alarm", the widget have to do not use the 'sleep' series functions.
243 * because those functions will generate alarm signal.
244 * then the module will be deactivated
246 * Enable alarm for detecting infinite loop
249 #if defined(_USE_ECORE_TIME_GET)
250 s_info.alarm_tv = ecore_time_get();
252 if (gettimeofday(&s_info.alarm_tv, NULL) < 0) {
253 ErrPrint("gettimeofday: %d\n", errno);
254 s_info.alarm_tv.tv_sec = 0;
255 s_info.alarm_tv.tv_usec = 0;
265 HAPI int fault_unmark_call(const char *pkgname, const char *filename, const char *funcname, int noalarm)
276 if (!s_info.disable_checker) {
277 widget_provider_send_ret(pkgname, filename, funcname);
282 HAPI void fault_disable_call_option(void)
284 s_info.disable_checker = 1;