4 * Copyright (c) 2017 Samsung Electronics Co., Ltd. All rights reserved.
6 * Contact: YoungHun Kim <yh8004.kim@samsung.com>
8 * Licensed under the Apache License, Version 2.0 (the "License");
9 * you may not use this file except in compliance with the License.
10 * You may obtain a copy of the License at
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 * See the License for the specific language governing permissions and
18 * limitations under the License.
22 #include "muse_server_private.h"
26 static struct sigaction ms_segv_old_action;
27 static struct sigaction ms_abrt_old_action;
28 static struct sigaction ms_term_old_action;
29 static struct sigaction ms_bus_old_action;
30 static struct sigaction ms_xcpu_old_action;
31 static struct sigaction ms_pipe_old_action;
33 static GMutex signal_lock;
35 static void _ms_signal_handler(int signo);
36 static void _ms_signal_debug_pid_info(int pid);
37 static void _ms_signal_backtrace(void *arg);
38 static void _ms_signal_sigaction(int signo, siginfo_t *si, void *arg);
40 static void _ms_signal_handler(int signo)
42 char client_buf[MUSE_MSG_LEN_MAX];
44 snprintf(client_buf, sizeof(client_buf), "signo (%d)", signo);
45 ms_log_write(client_buf);
47 LOGD("signo(%d)", signo);
49 ms_set_state(MUSE_SERVER_STATE_IDLE);
53 sigaction(SIGSEGV, &ms_segv_old_action, NULL);
56 sigaction(SIGABRT, &ms_abrt_old_action, NULL);
59 sigaction(SIGTERM, &ms_term_old_action, NULL);
62 sigaction(SIGBUS, &ms_bus_old_action, NULL);
65 sigaction(SIGXCPU, &ms_xcpu_old_action, NULL);
74 static void _ms_signal_debug_pid_info(int pid)
76 if (ms_is_log_enabled())
77 ms_log_debug_pid_info(pid);
80 static void _ms_signal_backtrace(void *arg)
82 void *trace[MUSE_MSG_LEN];
85 char **strings = NULL;
86 ucontext_t *uctxt = NULL;
88 char *sym_addr = NULL;
89 char err_msg[MUSE_MSG_LEN_MAX] = {'\0',};
90 char client_buf[MUSE_MSG_LEN_MAX];
92 g_mutex_lock(&signal_lock);
94 LOGE("----------BEGIN MUSE DYING MESSAGE----------");
96 tracesize = backtrace(trace, MUSE_MSG_LEN);
98 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
99 LOGE("backtrace error: %s", err_msg);
102 uctxt = (ucontext_t *)arg;
103 muse_return_if_fail(uctxt);
106 trace[1] = (void *) uctxt->uc_mcontext.gregs[REG_EIP];
107 #elif defined(REG_RIP)
108 trace[1] = (void *) uctxt->uc_mcontext.gregs[REG_RIP];
110 strings = backtrace_symbols(trace, tracesize);
112 strerror_r(errno, err_msg, MUSE_MSG_LEN_MAX);
113 LOGE("backtrace_symbols error: %s", err_msg);
115 /* skip the first stack frame because it just points here. */
116 for (idx = 1; idx < tracesize; idx++) {
117 sym_addr = g_strstr_len(strings[idx], strlen(strings[idx]), "[0x");
119 memset(&info, 0, sizeof(info));
120 if (sym_addr && dladdr((const void *)strtoul(sym_addr + 1, NULL, 16), &info) && info.dli_sname)
121 LOGE("[%u] %s %s", idx - 1, strings[idx], info.dli_sname);
123 LOGE("[%u] %s", idx - 1, strings[idx]);
124 if (ms_is_log_enabled()) {
125 snprintf(client_buf, sizeof(client_buf), "[%u] %s", idx - 1, strings[idx]);
126 ms_log_write(client_buf);
133 LOGE("----------END MUSE DYING MESSAGE----------");
135 g_mutex_unlock(&signal_lock);
138 static void _ms_signal_sigaction(int signo, siginfo_t *si, void *arg)
140 muse_return_if_fail(si);
141 muse_return_if_fail(arg);
143 ms_remove_ready_file();
145 ms_config_remove_lockfile();
147 _ms_signal_debug_pid_info(si->si_pid);
148 _ms_signal_backtrace(arg);
149 _ms_signal_handler(signo);
152 void ms_signal_init(void)
154 struct sigaction action;
156 memset(&action, 0, sizeof(struct sigaction));
157 sigemptyset(&action.sa_mask);
158 action.sa_sigaction = _ms_signal_sigaction;
159 action.sa_flags = SA_RESTART | SA_SIGINFO;
161 sigaction(SIGSEGV, &action, &ms_segv_old_action);
162 sigaction(SIGABRT, &action, &ms_abrt_old_action);
163 sigaction(SIGTERM, &action, &ms_term_old_action);
164 sigaction(SIGBUS, &action, &ms_bus_old_action);
165 sigaction(SIGXCPU, &action, &ms_xcpu_old_action);
168 action.sa_handler = SIG_IGN;
169 sigaction(SIGPIPE, &action, &ms_pipe_old_action);