[PATCH] Send TERMINATING event to Framework upon crash
abdoulaye berthe
berthe.ab
Wed Mar 18 10:40:05 PDT 2015
From: Abdoulaye Berthe <berthe.ab at gmail.com>
This sends a terminating event to Android Framework to report
wpa_supplicant crash. It is done by saving the initial crash handler
and regitering a new one. When a crash occurs, the new handler sends
a TERMINATE CTRL-EVENT to Android Framework and call the saved handler.
The TERMINATE CTRL-EVENT allows Android to detect supplicant crash.
Signed-off-by: Abdoulaye Berthe <abdoulaye.berthe at sonymobile.com>
---
src/utils/eloop.c | 67 +++++++++++++++++++++++++++++++++++++++++
src/utils/eloop.h | 19 ++++++++++++
wpa_supplicant/wpa_supplicant.c | 23 ++++++++++++++
3 files changed, 109 insertions(+)
diff --git a/src/utils/eloop.c b/src/utils/eloop.c
index 4a565eb..6e56737 100644
--- a/src/utils/eloop.c
+++ b/src/utils/eloop.c
@@ -30,6 +30,14 @@
#include <sys/epoll.h>
#endif /* CONFIG_ELOOP_EPOLL */
+#ifdef ANDROID
+struct eloop_saved_signal {
+ int signal;
+ void *signal_user_data;
+ signal_handler *handler;
+};
+#endif /* ANDROID */
+
struct eloop_sock {
int sock;
void *eloop_data;
@@ -101,6 +109,10 @@ struct eloop_data {
static struct eloop_data eloop;
+#ifdef ANDROID
+int saved_signal_count;
+struct eloop_saved_signal *saved_signals;
+#endif /* ANDROID */
#ifdef WPA_TRACE
@@ -883,6 +895,34 @@ int eloop_register_signal_terminate(eloop_signal_handler handler,
return ret;
}
+#ifdef ANDROID
+int eloop_register_signal_and_save_handler(int sig, void *handler, void *user_data)
+{
+ void (*pret)(int);
+ pret = signal(sig, handler);
+
+ if (pret != SIG_ERR) {
+ struct eloop_saved_signal *tmp;
+ tmp = os_realloc_array(saved_signals, saved_signal_count + 1,
+ sizeof(struct eloop_saved_signal));
+ if (tmp == NULL) {
+ return -1;
+ }
+
+ tmp[saved_signal_count].signal = sig;
+ tmp[saved_signal_count].handler = (signal_handler *) pret;
+ tmp[saved_signal_count].signal_user_data = user_data;
+ saved_signal_count ++;
+ saved_signals = tmp;
+ wpa_printf(MSG_DEBUG, "eloop_register_signal_sig_segv_handler success");
+ } else {
+ wpa_printf(MSG_ERROR, "eloop_register_signal_sig_segv_handler failure");
+ return -1;
+ }
+
+ return 0;
+}
+#endif /* ANDROID */
int eloop_register_signal_reconfig(eloop_signal_handler handler,
void *user_data)
@@ -1058,6 +1098,9 @@ void eloop_destroy(void)
eloop_sock_table_destroy(&eloop.writers);
eloop_sock_table_destroy(&eloop.exceptions);
os_free(eloop.signals);
+#ifdef ANDROID
+ os_free(saved_signals);
+#endif /* ANDROID */
#ifdef CONFIG_ELOOP_POLL
os_free(eloop.pollfds);
@@ -1111,3 +1154,27 @@ void eloop_wait_for_read_sock(int sock)
#ifdef CONFIG_ELOOP_SELECT
#undef CONFIG_ELOOP_SELECT
#endif /* CONFIG_ELOOP_SELECT */
+
+#ifdef ANDROID
+void * eloop_get_saved_signal_user_data(int sig)
+{
+ int i;
+ for (i = 0; i < saved_signal_count; i++) {
+ if (saved_signals[i].signal == sig) {
+ return saved_signals[i].signal_user_data;
+ }
+ }
+ return NULL;
+}
+
+signal_handler * eloop_get_saved_signal_handler(int sig)
+{
+ int i;
+ for (i = 0; i < saved_signal_count; i++) {
+ if (saved_signals[i].signal == sig) {
+ return saved_signals[i].handler;
+ }
+ }
+ return NULL;
+}
+#endif /* ANDROID */
diff --git a/src/utils/eloop.h b/src/utils/eloop.h
index 07b8c0d..1a20bf7 100644
--- a/src/utils/eloop.h
+++ b/src/utils/eloop.h
@@ -65,6 +65,10 @@ typedef void (*eloop_timeout_handler)(void *eloop_data, void *user_ctx);
*/
typedef void (*eloop_signal_handler)(int sig, void *signal_ctx);
+#ifdef ANDROID
+typedef void (*signal_handler)(int sig);
+#endif /* ANDROID */
+
/**
* eloop_init() - Initialize global event loop data
* Returns: 0 on success, -1 on failure
@@ -312,6 +316,15 @@ int eloop_register_signal_terminate(eloop_signal_handler handler,
int eloop_register_signal_reconfig(eloop_signal_handler handler,
void *user_data);
+#ifdef ANDROID
+/*
+ * eloop_register_signal_and_save_handler - Save old handler and register a
+ * new handler for signal.
+ */
+int eloop_register_signal_and_save_handler(int sig, void *handler,
+ void *user_data);
+#endif /* ANDROID */
+
/**
* eloop_run - Start the event loop
*
@@ -356,4 +369,10 @@ int eloop_terminated(void);
*/
void eloop_wait_for_read_sock(int sock);
+#ifdef ANDROID
+void * eloop_get_saved_signal_user_data(int sig);
+
+signal_handler * eloop_get_saved_signal_handler(int sig);
+#endif /* ANDROID */
+
#endif /* ELOOP_H */
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 19fb890..29cfdd7 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -812,6 +812,25 @@ static void wpa_supplicant_terminate(int sig, void *signal_ctx)
wpa_supplicant_terminate_proc(global);
}
+#ifdef ANDROID
+static void wpa_supplicant_process_crash_signal(int sig)
+{
+ /* Send terminating event to state machine and recall saved handler for crash report */
+ struct wpa_global *global;
+ struct wpa_supplicant *wpa_s;
+ global = (struct wpa_global *) eloop_get_saved_signal_user_data(sig);
+ if (global) {
+ wpa_s = global->ifaces;
+ wpa_dbg(wpa_s, MSG_DEBUG, "%s: sending WPA_EVENT_TERMINATING to ctrl socket", __func__);
+ wpa_msg_ctrl(wpa_s, MSG_INFO, WPA_EVENT_TERMINATING);
+ }
+
+ if (eloop_get_saved_signal_handler(sig) != NULL) {
+ (*eloop_get_saved_signal_handler(sig))(sig);
+ }
+}
+#endif /* ANDROID */
+
void wpa_supplicant_clear_status(struct wpa_supplicant *wpa_s)
{
@@ -4642,6 +4661,10 @@ int wpa_supplicant_run(struct wpa_global *global)
eloop_register_signal_terminate(wpa_supplicant_terminate, global);
eloop_register_signal_reconfig(wpa_supplicant_reconfig, global);
+#ifdef ANDROID
+ eloop_register_signal_and_save_handler(SIGSEGV, wpa_supplicant_process_crash_signal,
+ global);
+#endif /* ANDROID */
eloop_run();
--
2.3.3
More information about the Hostap
mailing list