From e3fdb6976e6afa273b7f7d4483b1f40c08f31177 Mon Sep 17 00:00:00 2001 From: Vitaliy Cherepanov Date: Fri, 25 Sep 2015 10:06:06 +0300 Subject: [PATCH] [FIX] wsi crash, deadlock Change-Id: I18174cc7071b6d3283db33996dbc02cff87d6d36 Signed-off-by: Vitaliy Cherepanov --- daemon/swap_debug.h | 6 ++++- daemon/wsi.c | 73 ++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 58 insertions(+), 21 deletions(-) diff --git a/daemon/swap_debug.h b/daemon/swap_debug.h index ff6608d..d49d6c2 100644 --- a/daemon/swap_debug.h +++ b/daemon/swap_debug.h @@ -29,6 +29,7 @@ #ifndef _DAEMON_DEBUG_H_ #define _DAEMON_DEBUG_H_ +#include #include // for uint64_t, int64_t #include // for pthread_mutex_t #include @@ -96,7 +97,10 @@ static inline void do_log(const char *prefix, const char *funcname, int line, .. { va_list ap; const char *fmt; - fprintf(stderr, "[%s][%f] (%s:%d):", prefix, get_uptime(), funcname, line); + fprintf(stderr, "[%s][%f] PID %u:%u (%s:%d):", prefix, get_uptime(), + (unsigned int)getpid(), + (unsigned int)syscall(SYS_gettid), + funcname, line); va_start(ap, line); fmt = va_arg(ap, const char *); diff --git a/daemon/wsi.c b/daemon/wsi.c index f925c99..fab3896 100644 --- a/daemon/wsi.c +++ b/daemon/wsi.c @@ -60,6 +60,17 @@ #define CLRSTAT(S, F) ((S) &= ~(F)) #define CHKSTAT(S, F) (((S) & (F)) ? 1: 0) + +#define LOG_STATUS LOGW(">>>>> state : %s %s %s %s %s %s\n",\ + CHKSTAT(pstate, PSTATE_DEFAULT)?"PSTATE_DEFAULT":"",\ + CHKSTAT(pstate, PSTATE_CONNECTED)?"PSTATE_CONNECTED":"",\ + CHKSTAT(pstate, PSTATE_PROFILING)?"PSTATE_PROFILING":"",\ + CHKSTAT(pstate, PSTATE_WAIT_ACK)?"PSTATE_WAIT_ACK":"",\ + CHKSTAT(pstate, PSTATE_TIMEOUT)?"PSTATE_TIMEOUT":"",\ + CHKSTAT(pstate, PSTATE_START)?"PSTATE_START":"",\ + CHKSTAT(pstate, PSTATE_DISCONNECT)?"PSTATE_DISCONNECT":"") + + enum protocol_names { PROTOCOL_PROFILING }; @@ -72,6 +83,7 @@ int pstate = PSTATE_DEFAULT; int request_id = 1; pthread_t wsi_start_thread = -1; +pthread_t wsi_handle_thread = -1; static void wsi_destroy(void); @@ -151,15 +163,13 @@ int wsi_set_smack_rules(const struct app_info_t *app_info) char *package_id; size_t id_maxlen = 128; - app_id = malloc(sizeof(char) * (strnlen(app_info->app_id, id_maxlen) + 1)); - + app_id = strndup(app_info->app_id, id_maxlen); if (app_id == NULL) { - LOGE("app id alloc error\n"); - ret = 1; + LOGE("cannot allocate memory\n"); + ret = -ENOMEM; goto exit; } - strcpy(app_id, app_info->app_id); package_id = strtok(app_id, delim); if (package_id != NULL) { @@ -206,6 +216,7 @@ static void send_request(const char *method) char buf[LWS_SEND_BUFFER_PRE_PADDING + MAX_REQUEST_LENGTH + LWS_SEND_BUFFER_POST_PADDING]; const char *payload; + size_t payload_len = 0; jobj = json_object_new_object(); if (jobj == NULL) { @@ -223,16 +234,22 @@ static void send_request(const char *method) LOGE("cannot parse json object (method: %s)\n", method); return; } - strncpy(buf, payload, MAX_REQUEST_LENGTH); - if (libwebsocket_write(wsi, (unsigned char *)buf, strlen(payload), + payload_len = strnlen(payload, MAX_REQUEST_LENGTH); + if (payload_len != MAX_REQUEST_LENGTH) + LOGI("json generated len: %d; msg: %s\n", payload_len, payload); + else + LOGE("bad payload!!!\n"); + + strncpy(buf, payload, MAX_REQUEST_LENGTH - 1); + + if (libwebsocket_write(wsi, (unsigned char *)buf, payload_len, LWS_WRITE_TEXT) < 0) { LOGE("cannot write to web socket (method: %s)\n", method); return; } SETSTAT(pstate, PSTATE_WAIT_ACK); - LOGI("json message send; len: %d; msg: %s\n", strlen(payload), payload); } static int profiling_callback(struct libwebsocket_context *context, @@ -252,10 +269,12 @@ static int profiling_callback(struct libwebsocket_context *context, send_request("Profiler.start"); break; + case LWS_CALLBACK_DEL_POLL_FD: + LOGE("LWS_CALLBACK_DEL_POLL_FD\n"); case LWS_CALLBACK_CLOSED: LOGI("Connection closed\n"); CLRSTAT(pstate, PSTATE_CONNECTED); - CLRSTAT(pstate, PSTATE_DISCONNECT); + SETSTAT(pstate, PSTATE_DISCONNECT); break; case LWS_CALLBACK_CLIENT_RECEIVE: @@ -314,7 +333,7 @@ static int profiling_callback(struct libwebsocket_context *context, break; case LWS_CALLBACK_CLIENT_CONNECTION_ERROR: - LOGE("Web socket connection error\n"); + LOGE("Web socket connection error. Falling down\n"); /* * TODO: need report to host about error. May be should stop * web profiling and/or launching web application @@ -343,7 +362,7 @@ static int init_wsi_conn(struct libwebsocket_context **context, struct libwebsocket **wsi, const char *address, int port) { - struct lws_context_creation_info info; + static struct lws_context_creation_info info; char host[32]; char origin[32]; const char *page = "/devtools/page/1"; @@ -351,6 +370,7 @@ static int init_wsi_conn(struct libwebsocket_context **context, sprintf(host, "%s:%d", address, port); sprintf(origin, "http://%s:%d", address, port); + LOGI(" host =<%s> origin = <%s>\n", host, origin); memset(&info, 0, sizeof(info)); @@ -388,9 +408,11 @@ static int init_wsi_conn(struct libwebsocket_context **context, static void *handle_ws_responses(void *arg) { while (CHKSTAT(pstate, PSTATE_START | PSTATE_PROFILING | - PSTATE_WAIT_ACK)) - libwebsocket_service(context, 50); + PSTATE_WAIT_ACK) && !CHKSTAT(pstate, PSTATE_DISCONNECT)) { + libwebsocket_service(context, 1000); + } + LOGI("handle response thread finished\n"); return NULL; } @@ -424,10 +446,12 @@ static int wsi_init(const char *address, int port) static void wsi_destroy(void) { if (CHKSTAT(pstate, PSTATE_CONNECTED)) { - if (CHKSTAT(pstate, PSTATE_WAIT_ACK)) + if (CHKSTAT(pstate, PSTATE_WAIT_ACK)) { SETSTAT(pstate, PSTATE_DISCONNECT); - else + } else { + LOGI("destroy context\n"); destroy_wsi_conn(context); + } } else { LOGW("Try disconnect when web socket not connected\n"); } @@ -435,11 +459,9 @@ static void wsi_destroy(void) static int wsi_start_profiling(void) { - pthread_t tid; - SETSTAT(pstate, PSTATE_START); - if (pthread_create(&tid, NULL, &handle_ws_responses, NULL)) { + if (pthread_create(&wsi_handle_thread, NULL, &handle_ws_responses, NULL)) { LOGE("Can't create handle_ws_ threads\n"); destroy_wsi_conn(context); return 1; @@ -498,9 +520,20 @@ void wsi_stop(void) LOGE("Cannot disable web application profiling\n"); } + SETSTAT(pstate, PSTATE_DISCONNECT); + if (wsi_start_thread != -1) pthread_join(wsi_start_thread, &thread_ret); - wsi_start_thread = -1; - wsi_destroy(); + + + if (wsi_handle_thread != -1) { + LOGI("wait handle thread"); + pthread_join(wsi_handle_thread, &thread_ret); + } + wsi_handle_thread = -1; + + destroy_wsi_conn(context); + + CLRSTAT(pstate, PSTATE_DISCONNECT); } -- 2.7.4