From 37bce7698bcc49c1ac9adac0671a8ba93db20bb3 Mon Sep 17 00:00:00 2001 From: Xu Jun <693788454@qq.com> Date: Wed, 26 Jan 2022 23:55:27 +0800 Subject: [PATCH 01/16] don't block gdbserver thread while executing --- .../libraries/debug-engine/debug_engine.c | 80 +++++++- .../libraries/debug-engine/debug_engine.h | 22 +++ core/iwasm/libraries/debug-engine/gdbserver.c | 173 +++++++++++++++--- core/iwasm/libraries/debug-engine/gdbserver.h | 16 ++ core/iwasm/libraries/debug-engine/handler.c | 70 ++++--- core/iwasm/libraries/debug-engine/handler.h | 6 + core/iwasm/libraries/debug-engine/packets.h | 3 + .../libraries/thread-mgr/thread_manager.c | 12 +- .../platform/common/posix/posix_socket.c | 16 ++ .../platform/include/platform_api_extension.h | 11 ++ core/shared/platform/windows/win_socket.c | 14 ++ 11 files changed, 366 insertions(+), 57 deletions(-) diff --git a/core/iwasm/libraries/debug-engine/debug_engine.c b/core/iwasm/libraries/debug-engine/debug_engine.c index 4fa34f5371..5bc7aaf4bc 100644 --- a/core/iwasm/libraries/debug-engine/debug_engine.c +++ b/core/iwasm/libraries/debug-engine/debug_engine.c @@ -24,6 +24,12 @@ typedef struct WASMDebugEngine { bool active; } WASMDebugEngine; +void +on_thread_stop_event(WASMDebugInstance *debug_inst, WASMExecEnv *exec_env) +{ + debug_inst->stopped_thread = exec_env; +} + static WASMDebugEngine *g_debug_engine; static uint32 current_instance_id = 1; @@ -104,6 +110,34 @@ control_thread_routine(void *arg) while (true) { os_mutex_lock(&control_thread->wait_lock); if (!should_stop(control_thread)) { + /* send thread stop reply */ + if (debug_inst->stopped_thread + && debug_inst->current_state == APP_RUNNING) { + uint32 status; + korp_tid tid; + + status = debug_inst->stopped_thread->current_status->signal_flag; + tid = debug_inst->stopped_thread->handle; + + if (debug_inst->stopped_thread->current_status->running_status + == STATUS_EXIT) { + /* If the thread exits, report "W00" if it's the last thread + * in the cluster, otherwise ignore this event */ + status = 0; + + if (debug_inst->cluster->exec_env_list.len != 1) { + debug_inst->stopped_thread = NULL; + continue; + } + } + + send_thread_stop_status(control_thread->server, status, tid); + + debug_inst->current_state = APP_STOPPED; + debug_inst->stopped_thread = NULL; + } + + /* Processing incoming requests */ if (!wasm_gdbserver_handle_packet(control_thread->server)) { control_thread->status = STOPPED; } @@ -148,8 +182,10 @@ wasm_debug_control_thread_create(WASMDebugInstance *debug_instance) /* wait until the debug control thread ready */ os_cond_wait(&debug_instance->wait_cond, &debug_instance->wait_lock); os_mutex_unlock(&debug_instance->wait_lock); - if (!control_thread->server) + if (!control_thread->server) { + os_thread_join(control_thread->tid, NULL); goto fail1; + } os_mutex_lock(&g_debug_engine->instance_list_lock); /* create control thread success, append debug instance to debug engine */ @@ -935,6 +971,11 @@ wasm_debug_instance_continue(WASMDebugInstance *instance) if (!instance) return false; + if (instance->current_state == APP_RUNNING) { + LOG_VERBOSE("Already in running state, ignore continue request"); + return false; + } + exec_env = bh_list_first_elem(&instance->cluster->exec_env_list); if (!exec_env) return false; @@ -943,6 +984,28 @@ wasm_debug_instance_continue(WASMDebugInstance *instance) wasm_cluster_thread_continue(exec_env); exec_env = bh_list_elem_next(exec_env); } + + instance->current_state = APP_RUNNING; + + return true; +} + +bool +wasm_debug_instance_interrupt_all_threads(WASMDebugInstance *instance) +{ + WASMExecEnv *exec_env; + + if (!instance) + return false; + + exec_env = bh_list_first_elem(&instance->cluster->exec_env_list); + if (!exec_env) + return false; + + while (exec_env) { + wasm_cluster_thread_send_signal(exec_env, WAMR_SIG_TRAP); + exec_env = bh_list_elem_next(exec_env); + } return true; } @@ -960,8 +1023,15 @@ wasm_debug_instance_kill(WASMDebugInstance *instance) while (exec_env) { wasm_cluster_thread_send_signal(exec_env, WAMR_SIG_TERM); + if (instance->current_state == APP_STOPPED) { + /* Resume all threads so they can receive the TERM signal */ + exec_env->current_status->running_status = STATUS_RUNNING; + os_cond_signal(&exec_env->wait_cond); + } exec_env = bh_list_elem_next(exec_env); } + + instance->current_state = APP_RUNNING; return true; } @@ -973,6 +1043,11 @@ wasm_debug_instance_singlestep(WASMDebugInstance *instance, korp_tid tid) if (!instance) return false; + if (instance->current_state == APP_RUNNING) { + LOG_VERBOSE("Already in running state, ignore step request"); + return false; + } + exec_env = bh_list_first_elem(&instance->cluster->exec_env_list); if (!exec_env) return false; @@ -984,6 +1059,9 @@ wasm_debug_instance_singlestep(WASMDebugInstance *instance, korp_tid tid) } exec_env = bh_list_elem_next(exec_env); } + + instance->current_state = APP_RUNNING; + return true; } diff --git a/core/iwasm/libraries/debug-engine/debug_engine.h b/core/iwasm/libraries/debug-engine/debug_engine.h index ef44543fba..f82399b3e0 100644 --- a/core/iwasm/libraries/debug-engine/debug_engine.h +++ b/core/iwasm/libraries/debug-engine/debug_engine.h @@ -35,6 +35,15 @@ typedef struct WASMDebugBreakPoint { uint64 orignal_data; } WASMDebugBreakPoint; +typedef enum debug_state_t { + /* Debugger state conversion sequence: + * DBG_LAUNCHING ---> APP_STOPPED <---> APP_RUNNING + */ + DBG_LAUNCHING, + APP_RUNNING, + APP_STOPPED +} debug_state_t; + typedef struct WASMDebugInstance { struct WASMDebugInstance *next; WASMDebugControlThread *control_thread; @@ -44,6 +53,13 @@ typedef struct WASMDebugInstance { korp_tid current_tid; korp_mutex wait_lock; korp_cond wait_cond; + /* Last stopped thread, it should be set to NULL when sending + * out the thread stop reply */ + volatile WASMExecEnv *stopped_thread; + /* Currently status of the debug instance, it will be set to + * RUNNING when receiving STEP/CONTINUE commands, and set to + * STOPPED when any thread stopped */ + volatile debug_state_t current_state; } WASMDebugInstance; typedef enum WASMDebugEventKind { @@ -77,6 +93,9 @@ typedef enum WasmAddressType { #define INVALIED_ADDR (0xFFFFFFFFFFFFFFFF) +void +on_thread_stop_event(WASMDebugInstance *debug_inst, WASMExecEnv *exec_env); + WASMDebugInstance * wasm_debug_instance_create(WASMCluster *cluster); @@ -152,6 +171,9 @@ bool wasm_debug_instance_remove_breakpoint(WASMDebugInstance *instance, uint64 addr, uint64 length); +bool +wasm_debug_instance_interrupt_all_threads(WASMDebugInstance *instance); + bool wasm_debug_instance_continue(WASMDebugInstance *instance); diff --git a/core/iwasm/libraries/debug-engine/gdbserver.c b/core/iwasm/libraries/debug-engine/gdbserver.c index 7d52b19155..d7ad42ad75 100644 --- a/core/iwasm/libraries/debug-engine/gdbserver.c +++ b/core/iwasm/libraries/debug-engine/gdbserver.c @@ -51,6 +51,14 @@ wasm_create_gdbserver(const char *host, int32 *port) memset(server, 0, sizeof(WASMGDBServer)); + if (!(server->receive_ctx = + wasm_runtime_malloc(sizeof(rsp_recv_context_t)))) { + LOG_ERROR("wasm gdb server error: failed to allocate memory"); + goto fail; + } + + memset(server->receive_ctx, 0, sizeof(rsp_recv_context_t)); + if (0 != os_socket_create(&listen_fd, 1)) { LOG_ERROR("wasm gdb server error: create socket failed"); goto fail; @@ -71,6 +79,8 @@ wasm_create_gdbserver(const char *host, int32 *port) os_socket_shutdown(listen_fd); os_socket_close(listen_fd); } + if (server->receive_ctx) + wasm_runtime_free(server->receive_ctx); if (server) wasm_runtime_free(server); return NULL; @@ -108,6 +118,9 @@ wasm_gdbserver_listen(WASMGDBServer *server) void wasm_close_gdbserver(WASMGDBServer *server) { + if (server->receive_ctx) { + wasm_runtime_free(server->receive_ctx); + } if (server->socket_fd > 0) { os_socket_shutdown(server->socket_fd); os_socket_close(server->socket_fd); @@ -125,51 +138,153 @@ handler_packet(WASMGDBServer *server, char request, char *payload) packet_handler_table[(int)request].handler(server, payload); } +static void +process_packet(WASMGDBServer *server) +{ + uint8 *inbuf = (uint8 *)server->receive_ctx->receive_buffer; + char request; + char *payload = NULL; + + // if (packet_size == 1) { + // LOG_VERBOSE("receive empty request, ignore it\n"); + // return; + // } + + request = inbuf[0]; + payload = (char *)&inbuf[1]; + + LOG_VERBOSE("receive request:%c %s\n", request, payload); + handler_packet(server, request, payload); + + // inbuf_erase_head(server, packet_size + 3); +} + +static inline void +push_byte(rsp_recv_context_t *ctx, unsigned char ch, bool checksum) +{ + if (ctx->receive_index >= sizeof(ctx->receive_buffer)) { + LOG_ERROR("RSP message buffer overflow"); + bh_assert(false); + } + + ctx->receive_buffer[ctx->receive_index++] = ch; + + if (checksum) { + ctx->check_sum += ch; + } +} + /** * The packet layout is: + * 1. Normal packet: * '$' + payload + '#' + checksum(2bytes) * ^ - * packetend_ptr + * packetend + * 2. Interrupt: + * 0x03 */ -static void -process_packet(WASMGDBServer *server) + +/* return: + * 0: incomplete message received + * 1: complete message received + * 2: interrupt message received + */ +static int +on_rsp_byte_arrive(unsigned char ch, rsp_recv_context_t *ctx) { - uint8 *inbuf = server->pkt.buf; - int32 inbuf_size = server->pkt.size; - uint8 *packetend_ptr = (uint8 *)memchr(inbuf, '#', inbuf_size); - int32 packet_size = (int32)(uintptr_t)(packetend_ptr - inbuf); - char request = inbuf[1]; - char *payload = NULL; - uint8 checksum = 0; + if (ctx->phase == Phase_Idle) { + ctx->receive_index = 0; + ctx->check_sum = 0; + + if (ch == 0x03) { + LOG_VERBOSE("Receive interrupt package"); + return 2; + } + else if (ch == '$') { + ctx->phase = Phase_Payload; + } - if (packet_size == 1) { - LOG_VERBOSE("receive empty request, ignore it\n"); - return; + return 0; } + else if (ctx->phase == Phase_Payload) { + if (ch == '#') { + ctx->phase = Phase_Checksum; + push_byte(ctx, ch, false); + } + else { + push_byte(ctx, ch, true); + } - bh_assert('$' == inbuf[0]); - inbuf[packet_size] = '\0'; + return 0; + } + else if (ctx->phase == Phase_Checksum) { + ctx->size_in_phase++; + push_byte(ctx, ch, false); - for (int i = 1; i < packet_size; i++) - checksum += inbuf[i]; - bh_assert( - checksum - == (hex(inbuf[packet_size + 1]) << 4 | hex(inbuf[packet_size + 2]))); + if (ctx->size_in_phase == 2) { + ctx->size_in_phase = 0; - payload = (char *)&inbuf[2]; + if ((hex(ctx->receive_buffer[ctx->receive_index - 2]) << 4 + | hex(ctx->receive_buffer[ctx->receive_index - 1])) + != ctx->check_sum) { + LOG_WARNING("RSP package checksum error, ignore it"); + ctx->phase = Phase_Idle; + return 0; + } + else { + /* Change # to \0 */ + ctx->receive_buffer[ctx->receive_index - 3] = '\0'; + ctx->phase = Phase_Idle; + return 1; + } + } - LOG_VERBOSE("receive request:%c %s\n", request, payload); - handler_packet(server, request, payload); + return 0; + } - inbuf_erase_head(server, packet_size + 3); + /* Should never reach here */ + bh_assert(false); + return 0; } bool wasm_gdbserver_handle_packet(WASMGDBServer *server) { - bool ret; - ret = read_packet(server); - if (ret) - process_packet(server); - return ret; + int32 n; + char buf[1024]; + + if (os_socket_settimeout(server->socket_fd, 1000) != 0) { + LOG_ERROR("Set socket recv timeout failed"); + return false; + } + + n = os_socket_recv(server->socket_fd, buf, sizeof(buf)); + + if (n == 0) { + LOG_VERBOSE("Debugger disconnected"); + return false; + } + else if (n < 0) { + /* No bytes arrived */ + return true; + } + else { + int32 i, ret; + + for (i = 0; i < n; i++) { + ret = on_rsp_byte_arrive(buf[i], server->receive_ctx); + + if (ret == 1) { + if (!server->noack) + write_data_raw(server, (uint8 *)"+", 1); + + process_packet(server); + } + else if (ret == 2) { + handle_interrupt(server); + } + } + } + + return true; } diff --git a/core/iwasm/libraries/debug-engine/gdbserver.h b/core/iwasm/libraries/debug-engine/gdbserver.h index f5d0453510..fc17fb8000 100644 --- a/core/iwasm/libraries/debug-engine/gdbserver.h +++ b/core/iwasm/libraries/debug-engine/gdbserver.h @@ -18,6 +18,21 @@ enum GDBStoppointType { eWatchpointRead, eWatchpointReadWrite }; +typedef enum rsp_recv_phase_t { + Phase_Idle, + Phase_Payload, + Phase_Checksum +} rsp_recv_phase_t; + +/* Remote Serial Protocol Receive Context */ +typedef struct rsp_recv_context_t { + rsp_recv_phase_t phase; + uint16 receive_index; + uint16 size_in_phase; + uint8 check_sum; + /* RSP packet should not be too long */ + char receive_buffer[1024]; +} rsp_recv_context_t; typedef struct WasmDebugPacket { unsigned char buf[PACKET_BUF_SIZE]; uint32 size; @@ -30,6 +45,7 @@ typedef struct WASMGDBServer { WasmDebugPacket pkt; bool noack; struct WASMDebugControlThread *thread; + rsp_recv_context_t *receive_ctx; } WASMGDBServer; WASMGDBServer * diff --git a/core/iwasm/libraries/debug-engine/handler.c b/core/iwasm/libraries/debug-engine/handler.c index b746a1c1c7..0e52c5aad6 100644 --- a/core/iwasm/libraries/debug-engine/handler.c +++ b/core/iwasm/libraries/debug-engine/handler.c @@ -26,8 +26,11 @@ wasm_debug_handler_deinit() os_mutex_destroy(&tmpbuf_lock); } -static void -send_thread_stop_status(WASMGDBServer *server, uint32 status, korp_tid tid); +void +handle_interrupt(WASMGDBServer *server) +{ + wasm_debug_instance_interrupt_all_threads(server->thread->debug_instance); +} void handle_generay_set(WASMGDBServer *server, char *payload) @@ -322,7 +325,7 @@ handle_generay_query(WASMGDBServer *server, char *payload) } } -static void +void send_thread_stop_status(WASMGDBServer *server, uint32 status, korp_tid tid) { int32 len = 0; @@ -391,7 +394,7 @@ handle_v_packet(WASMGDBServer *server, char *payload) { const char *name; char *args; - uint32 status; + // uint32 status; args = strchr(payload, ';'); if (args) @@ -428,10 +431,10 @@ handle_v_packet(WASMGDBServer *server, char *payload) server->thread->debug_instance); } - tid = wasm_debug_instance_wait_thread( - (WASMDebugInstance *)server->thread->debug_instance, - tid, &status); - send_thread_stop_status(server, status, tid); + // tid = wasm_debug_instance_wait_thread( + // (WASMDebugInstance *)server->thread->debug_instance, + // tid, &status); + // send_thread_stop_status(server, status, tid); } } } @@ -441,14 +444,30 @@ handle_v_packet(WASMGDBServer *server, char *payload) void handle_threadstop_request(WASMGDBServer *server, char *payload) { - korp_tid tid = wasm_debug_instance_get_tid( - (WASMDebugInstance *)server->thread->debug_instance); + korp_tid tid; uint32 status; + WASMDebugInstance *debug_inst = + (WASMDebugInstance *)server->thread->debug_instance; + bh_assert(debug_inst); + + /* According to + https://sourceware.org/gdb/onlinedocs/gdb/Packets.html#Packets, the "?" + package should be sent when connection is first established to query the + reason the target halted */ + bh_assert(debug_inst->current_state == DBG_LAUNCHING); - tid = wasm_debug_instance_wait_thread( - (WASMDebugInstance *)server->thread->debug_instance, tid, &status); + /* Waiting for the stop event */ + while (!debug_inst->stopped_thread); + + tid = debug_inst->stopped_thread->handle; + status = debug_inst->stopped_thread->current_status->signal_flag; + + wasm_debug_instance_set_cur_thread(debug_inst, tid); send_thread_stop_status(server, status, tid); + + debug_inst->current_state = APP_STOPPED; + debug_inst->stopped_thread = NULL; } void @@ -611,37 +630,36 @@ handle_remove_break(WASMGDBServer *server, char *payload) void handle_continue_request(WASMGDBServer *server, char *payload) { - korp_tid tid; - uint32 status; + // korp_tid tid; wasm_debug_instance_continue( (WASMDebugInstance *)server->thread->debug_instance); - tid = wasm_debug_instance_get_tid( - (WASMDebugInstance *)server->thread->debug_instance); + // tid = wasm_debug_instance_get_tid( + // (WASMDebugInstance *)server->thread->debug_instance); - tid = wasm_debug_instance_wait_thread( - (WASMDebugInstance *)server->thread->debug_instance, tid, &status); + // tid = wasm_debug_instance_wait_thread( + // (WASMDebugInstance *)server->thread->debug_instance, tid, &status); - send_thread_stop_status(server, status, tid); + // send_thread_stop_status(server, status, tid); } void handle_kill_request(WASMGDBServer *server, char *payload) { - korp_tid tid; - uint32 status; + // korp_tid tid; + // uint32 status; wasm_debug_instance_kill( (WASMDebugInstance *)server->thread->debug_instance); - tid = wasm_debug_instance_get_tid( - (WASMDebugInstance *)server->thread->debug_instance); + // tid = wasm_debug_instance_get_tid( + // (WASMDebugInstance *)server->thread->debug_instance); - tid = wasm_debug_instance_wait_thread( - (WASMDebugInstance *)server->thread->debug_instance, tid, &status); + // tid = wasm_debug_instance_wait_thread( + // (WASMDebugInstance *)server->thread->debug_instance, tid, &status); - send_thread_stop_status(server, status, tid); + // send_thread_stop_status(server, status, tid); } static void diff --git a/core/iwasm/libraries/debug-engine/handler.h b/core/iwasm/libraries/debug-engine/handler.h index d64b73ce43..b2db17b411 100644 --- a/core/iwasm/libraries/debug-engine/handler.h +++ b/core/iwasm/libraries/debug-engine/handler.h @@ -14,6 +14,9 @@ wasm_debug_handler_init(); void wasm_debug_handler_deinit(); +void +handle_interrupt(WASMGDBServer *server); + void handle_generay_set(WASMGDBServer *server, char *payload); @@ -58,4 +61,7 @@ handle_kill_request(WASMGDBServer *server, char *payload); void handle____request(WASMGDBServer *server, char *payload); + +void +send_thread_stop_status(WASMGDBServer *server, uint32 status, korp_tid tid); #endif diff --git a/core/iwasm/libraries/debug-engine/packets.h b/core/iwasm/libraries/debug-engine/packets.h index 7361bd6dfd..5287d4794a 100644 --- a/core/iwasm/libraries/debug-engine/packets.h +++ b/core/iwasm/libraries/debug-engine/packets.h @@ -8,6 +8,9 @@ #include "gdbserver.h" +void +write_data_raw(WASMGDBServer *gdbserver, const uint8 *data, ssize_t len); + bool read_packet(WASMGDBServer *gdbserver); diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.c b/core/iwasm/libraries/thread-mgr/thread_manager.c index 8db457c275..efc74a76eb 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.c +++ b/core/iwasm/libraries/thread-mgr/thread_manager.c @@ -284,6 +284,16 @@ wasm_cluster_del_exec_env(WASMCluster *cluster, WASMExecEnv *exec_env) { bool ret = true; bh_assert(exec_env->cluster == cluster); + +#if WASM_ENABLE_DEBUG_INTERP != 0 + /* Wait for debugger control thread to process the + stop event of this thread */ + if (cluster->debug_inst) { + while (cluster->debug_inst->stopped_thread == exec_env) { + } + } +#endif + os_mutex_lock(&cluster->lock); if (bh_list_remove(&cluster->exec_env_list, exec_env) != 0) ret = false; @@ -564,7 +574,7 @@ notify_debug_instance(WASMExecEnv *exec_env) } os_mutex_lock(&cluster->debug_inst->wait_lock); - os_cond_signal(&cluster->debug_inst->wait_cond); + on_thread_stop_event(cluster->debug_inst, exec_env); os_mutex_unlock(&cluster->debug_inst->wait_lock); } diff --git a/core/shared/platform/common/posix/posix_socket.c b/core/shared/platform/common/posix/posix_socket.c index 6492724622..fd325a4f83 100644 --- a/core/shared/platform/common/posix/posix_socket.c +++ b/core/shared/platform/common/posix/posix_socket.c @@ -71,6 +71,22 @@ os_socket_bind(bh_socket_t socket, const char *host, int *port) return BHT_ERROR; } +int +os_socket_settimeout(bh_socket_t socket, unsigned long long int timeout_us) +{ + struct timeval tv; + tv.tv_sec = timeout_us / 1000000UL; + tv.tv_usec = timeout_us % 1000000UL; + + if (setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, + sizeof(tv)) + != 0) { + return BHT_ERROR; + } + + return BHT_OK; +} + int os_socket_listen(bh_socket_t socket, int max_client) { diff --git a/core/shared/platform/include/platform_api_extension.h b/core/shared/platform/include/platform_api_extension.h index cd3c7e95af..2ee5c67a2d 100644 --- a/core/shared/platform/include/platform_api_extension.h +++ b/core/shared/platform/include/platform_api_extension.h @@ -226,6 +226,17 @@ os_socket_create(bh_socket_t *sock, int tcp_or_udp); int os_socket_bind(bh_socket_t socket, const char *addr, int *port); +/** + * Set timeout for the given socket + * + * @param socket the socket to set timeout + * @param timeout_us timeout in microseconds + * + * @return 0 if success, -1 otherwise + */ +int +os_socket_settimeout(bh_socket_t socket, unsigned long long int timeout_us); + /** * Make the socket as a passive socket to accept incoming connection requests * diff --git a/core/shared/platform/windows/win_socket.c b/core/shared/platform/windows/win_socket.c index 0057aeeda5..e71063481d 100644 --- a/core/shared/platform/windows/win_socket.c +++ b/core/shared/platform/windows/win_socket.c @@ -85,6 +85,20 @@ os_socket_bind(bh_socket_t socket, const char *host, int *port) return BHT_ERROR; } +int +os_socket_settimeout(bh_socket_t socket, unsigned long long int timeout_us) +{ + DWORD tv = timeout_us / 1000UL; + + if (setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, + sizeof(tv)) + != 0) { + return BHT_ERROR; + } + + return BHT_OK; +} + int os_socket_listen(bh_socket_t socket, int max_client) { From 21dbc4d521958bcf279e451eec892d64a37358f6 Mon Sep 17 00:00:00 2001 From: Xu Jun <693788454@qq.com> Date: Thu, 27 Jan 2022 11:20:53 +0800 Subject: [PATCH 02/16] fix some issue about current thread tid --- core/iwasm/libraries/debug-engine/debug_engine.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/core/iwasm/libraries/debug-engine/debug_engine.c b/core/iwasm/libraries/debug-engine/debug_engine.c index 5bc7aaf4bc..f166c2184d 100644 --- a/core/iwasm/libraries/debug-engine/debug_engine.c +++ b/core/iwasm/libraries/debug-engine/debug_engine.c @@ -131,6 +131,9 @@ control_thread_routine(void *arg) } } + wasm_debug_instance_set_cur_thread( + debug_inst, debug_inst->stopped_thread->handle); + send_thread_stop_status(control_thread->server, status, tid); debug_inst->current_state = APP_STOPPED; @@ -574,7 +577,8 @@ wasm_debug_instance_get_pc(WASMDebugInstance *instance) return 0; exec_env = wasm_debug_instance_get_current_env(instance); - if ((exec_env->cur_frame != NULL) && (exec_env->cur_frame->ip != NULL)) { + if ((exec_env != NULL) && (exec_env->cur_frame != NULL) + && (exec_env->cur_frame->ip != NULL)) { WASMModuleInstance *module_inst = (WASMModuleInstance *)exec_env->module_inst; return WASM_ADDR( From 7b1c1050ebb8697f685df7e645524fcf71c173e7 Mon Sep 17 00:00:00 2001 From: Xu Jun <693788454@qq.com> Date: Thu, 27 Jan 2022 21:21:20 +0800 Subject: [PATCH 03/16] remove unused functions --- core/iwasm/common/wasm_exec_env.c | 4 +- .../libraries/debug-engine/debug_engine.c | 41 +------------------ .../libraries/debug-engine/debug_engine.h | 6 +-- core/iwasm/libraries/debug-engine/gdbserver.c | 1 + core/iwasm/libraries/debug-engine/handler.c | 27 ------------ .../libraries/thread-mgr/thread_manager.c | 10 ++++- 6 files changed, 14 insertions(+), 75 deletions(-) diff --git a/core/iwasm/common/wasm_exec_env.c b/core/iwasm/common/wasm_exec_env.c index 6a3af642d0..1d5da53492 100644 --- a/core/iwasm/common/wasm_exec_env.c +++ b/core/iwasm/common/wasm_exec_env.c @@ -160,10 +160,12 @@ wasm_exec_env_destroy(WASMExecEnv *exec_env) /* Terminate all sub-threads */ WASMCluster *cluster = wasm_exec_env_get_cluster(exec_env); if (cluster) { + wasm_cluster_terminate_all_except_self(cluster, exec_env); #if WASM_ENABLE_DEBUG_INTERP != 0 + /* Must fire exit event after other threads exits, otherwise + the stopped thread will be overrided by other threads */ wasm_cluster_thread_exited(exec_env); #endif - wasm_cluster_terminate_all_except_self(cluster, exec_env); wasm_cluster_del_exec_env(cluster, exec_env); } #endif /* end of WASM_ENABLE_THREAD_MGR */ diff --git a/core/iwasm/libraries/debug-engine/debug_engine.c b/core/iwasm/libraries/debug-engine/debug_engine.c index f166c2184d..b61e81212a 100644 --- a/core/iwasm/libraries/debug-engine/debug_engine.c +++ b/core/iwasm/libraries/debug-engine/debug_engine.c @@ -127,6 +127,7 @@ control_thread_routine(void *arg) if (debug_inst->cluster->exec_env_list.len != 1) { debug_inst->stopped_thread = NULL; + os_mutex_unlock(&control_thread->wait_lock); continue; } } @@ -506,46 +507,6 @@ wasm_debug_instance_get_tids(WASMDebugInstance *instance, korp_tid tids[], return threads_num; } -static WASMExecEnv * -get_stopped_thread(WASMCluster *cluster) -{ - WASMExecEnv *exec_env; - - exec_env = bh_list_first_elem(&cluster->exec_env_list); - while (exec_env) { - if (exec_env->current_status->running_status != STATUS_RUNNING) { - return exec_env; - } - exec_env = bh_list_elem_next(exec_env); - } - - return NULL; -} - -korp_tid -wasm_debug_instance_wait_thread(WASMDebugInstance *instance, korp_tid tid, - uint32 *status) -{ - WASMExecEnv *exec_env = NULL; - - os_mutex_lock(&instance->wait_lock); - while ((instance->cluster->exec_env_list.len != 0) - && ((exec_env = get_stopped_thread(instance->cluster)) == NULL)) { - os_cond_wait(&instance->wait_cond, &instance->wait_lock); - } - os_mutex_unlock(&instance->wait_lock); - - /* If cluster has no exec_env, then this whole cluster is exiting */ - if (instance->cluster->exec_env_list.len == 0) { - *status = 0; - return 0; - } - - instance->current_tid = exec_env->handle; - *status = (uint32)exec_env->current_status->signal_flag; - return exec_env->handle; -} - uint32 wasm_debug_instance_get_thread_status(WASMDebugInstance *instance, korp_tid tid) { diff --git a/core/iwasm/libraries/debug-engine/debug_engine.h b/core/iwasm/libraries/debug-engine/debug_engine.h index f82399b3e0..5dd8dca8eb 100644 --- a/core/iwasm/libraries/debug-engine/debug_engine.h +++ b/core/iwasm/libraries/debug-engine/debug_engine.h @@ -55,7 +55,7 @@ typedef struct WASMDebugInstance { korp_cond wait_cond; /* Last stopped thread, it should be set to NULL when sending * out the thread stop reply */ - volatile WASMExecEnv *stopped_thread; + WASMExecEnv *volatile stopped_thread; /* Currently status of the debug instance, it will be set to * RUNNING when receiving STEP/CONTINUE commands, and set to * STOPPED when any thread stopped */ @@ -180,10 +180,6 @@ wasm_debug_instance_continue(WASMDebugInstance *instance); bool wasm_debug_instance_kill(WASMDebugInstance *instance); -korp_tid -wasm_debug_instance_wait_thread(WASMDebugInstance *instance, korp_tid tid, - uint32 *status); - uint32 wasm_debug_instance_get_thread_status(WASMDebugInstance *instance, korp_tid tid); diff --git a/core/iwasm/libraries/debug-engine/gdbserver.c b/core/iwasm/libraries/debug-engine/gdbserver.c index d7ad42ad75..baff522102 100644 --- a/core/iwasm/libraries/debug-engine/gdbserver.c +++ b/core/iwasm/libraries/debug-engine/gdbserver.c @@ -281,6 +281,7 @@ wasm_gdbserver_handle_packet(WASMGDBServer *server) process_packet(server); } else if (ret == 2) { + LOG_VERBOSE("Received interrupt package"); handle_interrupt(server); } } diff --git a/core/iwasm/libraries/debug-engine/handler.c b/core/iwasm/libraries/debug-engine/handler.c index 0e52c5aad6..cb77cc4563 100644 --- a/core/iwasm/libraries/debug-engine/handler.c +++ b/core/iwasm/libraries/debug-engine/handler.c @@ -394,7 +394,6 @@ handle_v_packet(WASMGDBServer *server, char *payload) { const char *name; char *args; - // uint32 status; args = strchr(payload, ';'); if (args) @@ -430,11 +429,6 @@ handle_v_packet(WASMGDBServer *server, char *payload) (WASMDebugInstance *) server->thread->debug_instance); } - - // tid = wasm_debug_instance_wait_thread( - // (WASMDebugInstance *)server->thread->debug_instance, - // tid, &status); - // send_thread_stop_status(server, status, tid); } } } @@ -630,36 +624,15 @@ handle_remove_break(WASMGDBServer *server, char *payload) void handle_continue_request(WASMGDBServer *server, char *payload) { - // korp_tid tid; - wasm_debug_instance_continue( (WASMDebugInstance *)server->thread->debug_instance); - - // tid = wasm_debug_instance_get_tid( - // (WASMDebugInstance *)server->thread->debug_instance); - - // tid = wasm_debug_instance_wait_thread( - // (WASMDebugInstance *)server->thread->debug_instance, tid, &status); - - // send_thread_stop_status(server, status, tid); } void handle_kill_request(WASMGDBServer *server, char *payload) { - // korp_tid tid; - // uint32 status; - wasm_debug_instance_kill( (WASMDebugInstance *)server->thread->debug_instance); - - // tid = wasm_debug_instance_get_tid( - // (WASMDebugInstance *)server->thread->debug_instance); - - // tid = wasm_debug_instance_wait_thread( - // (WASMDebugInstance *)server->thread->debug_instance, tid, &status); - - // send_thread_stop_status(server, status, tid); } static void diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.c b/core/iwasm/libraries/thread-mgr/thread_manager.c index efc74a76eb..88ecc2fce7 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.c +++ b/core/iwasm/libraries/thread-mgr/thread_manager.c @@ -287,10 +287,14 @@ wasm_cluster_del_exec_env(WASMCluster *cluster, WASMExecEnv *exec_env) #if WASM_ENABLE_DEBUG_INTERP != 0 /* Wait for debugger control thread to process the - stop event of this thread */ + stop event of this thread */ if (cluster->debug_inst) { + /* lock the debug_inst->wait_lock so + other threads can't fire stop events */ + os_mutex_lock(&cluster->debug_inst->wait_lock); while (cluster->debug_inst->stopped_thread == exec_env) { } + os_mutex_unlock(&cluster->debug_inst->wait_lock); } #endif @@ -457,6 +461,9 @@ thread_manager_start_routine(void *arg) free_aux_stack(cluster, exec_env->aux_stack_bottom.bottom); /* Detach the native thread here to ensure the resources are freed */ wasm_cluster_detach_thread(exec_env); +#if WASM_ENABLE_DEBUG_INTERP != 0 + wasm_cluster_thread_exited(exec_env); +#endif /* Remove and destroy exec_env */ wasm_cluster_del_exec_env(cluster, exec_env); wasm_exec_env_destroy_internal(exec_env); @@ -754,7 +761,6 @@ wasm_cluster_cancel_thread(WASMExecEnv *exec_env) /* Set the termination flag */ #if WASM_ENABLE_DEBUG_INTERP != 0 wasm_cluster_thread_send_signal(exec_env, WAMR_SIG_TERM); - wasm_cluster_thread_exited(exec_env); #else exec_env->suspend_flags.flags |= 0x01; #endif From 65ccc264b7b8bef3b8046f049be57873a4910384 Mon Sep 17 00:00:00 2001 From: Xu Jun <693788454@qq.com> Date: Thu, 27 Jan 2022 21:41:53 +0800 Subject: [PATCH 04/16] auto format --- core/iwasm/libraries/debug-engine/debug_engine.c | 3 ++- core/iwasm/libraries/debug-engine/handler.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/core/iwasm/libraries/debug-engine/debug_engine.c b/core/iwasm/libraries/debug-engine/debug_engine.c index b61e81212a..d831173a84 100644 --- a/core/iwasm/libraries/debug-engine/debug_engine.c +++ b/core/iwasm/libraries/debug-engine/debug_engine.c @@ -116,7 +116,8 @@ control_thread_routine(void *arg) uint32 status; korp_tid tid; - status = debug_inst->stopped_thread->current_status->signal_flag; + status = + debug_inst->stopped_thread->current_status->signal_flag; tid = debug_inst->stopped_thread->handle; if (debug_inst->stopped_thread->current_status->running_status diff --git a/core/iwasm/libraries/debug-engine/handler.c b/core/iwasm/libraries/debug-engine/handler.c index cb77cc4563..e2cd450844 100644 --- a/core/iwasm/libraries/debug-engine/handler.c +++ b/core/iwasm/libraries/debug-engine/handler.c @@ -451,7 +451,8 @@ handle_threadstop_request(WASMGDBServer *server, char *payload) bh_assert(debug_inst->current_state == DBG_LAUNCHING); /* Waiting for the stop event */ - while (!debug_inst->stopped_thread); + while (!debug_inst->stopped_thread) { + } tid = debug_inst->stopped_thread->handle; status = debug_inst->stopped_thread->current_status->signal_flag; From 02d653dfb39ce620d25de63b15f67e743956a50e Mon Sep 17 00:00:00 2001 From: Xu Jun <693788454@qq.com> Date: Thu, 27 Jan 2022 21:51:33 +0800 Subject: [PATCH 05/16] move mutex lock to debug_engine --- core/iwasm/libraries/debug-engine/debug_engine.c | 2 ++ core/iwasm/libraries/thread-mgr/thread_manager.c | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/core/iwasm/libraries/debug-engine/debug_engine.c b/core/iwasm/libraries/debug-engine/debug_engine.c index d831173a84..41484a4f78 100644 --- a/core/iwasm/libraries/debug-engine/debug_engine.c +++ b/core/iwasm/libraries/debug-engine/debug_engine.c @@ -27,7 +27,9 @@ typedef struct WASMDebugEngine { void on_thread_stop_event(WASMDebugInstance *debug_inst, WASMExecEnv *exec_env) { + os_mutex_lock(&debug_inst->wait_lock); debug_inst->stopped_thread = exec_env; + os_mutex_unlock(&debug_inst->wait_lock); } static WASMDebugEngine *g_debug_engine; diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.c b/core/iwasm/libraries/thread-mgr/thread_manager.c index 88ecc2fce7..0d83fdcbf7 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.c +++ b/core/iwasm/libraries/thread-mgr/thread_manager.c @@ -580,9 +580,7 @@ notify_debug_instance(WASMExecEnv *exec_env) return; } - os_mutex_lock(&cluster->debug_inst->wait_lock); on_thread_stop_event(cluster->debug_inst, exec_env); - os_mutex_unlock(&cluster->debug_inst->wait_lock); } void From b0570cd7ad0019b1ffd1867ed60fa750878d1085 Mon Sep 17 00:00:00 2001 From: Xu Jun <693788454@qq.com> Date: Thu, 27 Jan 2022 22:11:30 +0800 Subject: [PATCH 06/16] remove more unused codes --- .../libraries/debug-engine/debug_engine.c | 3 + core/iwasm/libraries/debug-engine/gdbserver.c | 17 ++-- core/iwasm/libraries/debug-engine/handler.c | 8 +- core/iwasm/libraries/debug-engine/packets.c | 87 ------------------- core/iwasm/libraries/debug-engine/packets.h | 6 -- 5 files changed, 15 insertions(+), 106 deletions(-) diff --git a/core/iwasm/libraries/debug-engine/debug_engine.c b/core/iwasm/libraries/debug-engine/debug_engine.c index 41484a4f78..750359d540 100644 --- a/core/iwasm/libraries/debug-engine/debug_engine.c +++ b/core/iwasm/libraries/debug-engine/debug_engine.c @@ -128,6 +128,9 @@ control_thread_routine(void *arg) * in the cluster, otherwise ignore this event */ status = 0; + /* By design, all the other threads should stopped at this + * moment, so it is safe to access the exec_env_list.len + * without lock */ if (debug_inst->cluster->exec_env_list.len != 1) { debug_inst->stopped_thread = NULL; os_mutex_unlock(&control_thread->wait_lock); diff --git a/core/iwasm/libraries/debug-engine/gdbserver.c b/core/iwasm/libraries/debug-engine/gdbserver.c index baff522102..e91ac828b3 100644 --- a/core/iwasm/libraries/debug-engine/gdbserver.c +++ b/core/iwasm/libraries/debug-engine/gdbserver.c @@ -145,18 +145,11 @@ process_packet(WASMGDBServer *server) char request; char *payload = NULL; - // if (packet_size == 1) { - // LOG_VERBOSE("receive empty request, ignore it\n"); - // return; - // } - request = inbuf[0]; payload = (char *)&inbuf[1]; LOG_VERBOSE("receive request:%c %s\n", request, payload); handler_packet(server, request, payload); - - // inbuf_erase_head(server, packet_size + 3); } static inline void @@ -265,8 +258,14 @@ wasm_gdbserver_handle_packet(WASMGDBServer *server) return false; } else if (n < 0) { - /* No bytes arrived */ - return true; + if (errno == EAGAIN || errno == EWOULDBLOCK) { + /* No bytes arrived */ + return true; + } + else { + LOG_ERROR("Socket receive error"); + return false; + } } else { int32 i, ret; diff --git a/core/iwasm/libraries/debug-engine/handler.c b/core/iwasm/libraries/debug-engine/handler.c index e2cd450844..0cbadb52fb 100644 --- a/core/iwasm/libraries/debug-engine/handler.c +++ b/core/iwasm/libraries/debug-engine/handler.c @@ -94,7 +94,7 @@ process_xfer(WASMGDBServer *server, const char *name, char *args) } void -porcess_wasm_local(WASMGDBServer *server, char *args) +process_wasm_local(WASMGDBServer *server, char *args) { int32 frame_index; int32 local_index; @@ -117,7 +117,7 @@ porcess_wasm_local(WASMGDBServer *server, char *args) } void -porcess_wasm_global(WASMGDBServer *server, char *args) +process_wasm_global(WASMGDBServer *server, char *args) { int32 frame_index; int32 global_index; @@ -301,11 +301,11 @@ handle_generay_query(WASMGDBServer *server, char *payload) } if (args && (!strcmp(name, "WasmLocal"))) { - porcess_wasm_local(server, args); + process_wasm_local(server, args); } if (args && (!strcmp(name, "WasmGlobal"))) { - porcess_wasm_global(server, args); + process_wasm_global(server, args); } if (!strcmp(name, "Offsets")) { diff --git a/core/iwasm/libraries/debug-engine/packets.c b/core/iwasm/libraries/debug-engine/packets.c index e8b80b4e3e..1bdb3d2ce8 100644 --- a/core/iwasm/libraries/debug-engine/packets.c +++ b/core/iwasm/libraries/debug-engine/packets.c @@ -7,56 +7,6 @@ #include "packets.h" #include "gdbserver.h" -void -pktbuf_insert(WASMGDBServer *gdbserver, const uint8 *buf, ssize_t len) -{ - WasmDebugPacket *pkt = &gdbserver->pkt; - - if ((unsigned long)(pkt->size + len) >= sizeof(pkt->buf)) { - LOG_ERROR("Packet buffer overflow"); - exit(-2); - } - - memcpy(pkt->buf + pkt->size, buf, len); - pkt->size += len; -} - -void -pktbuf_erase_head(WASMGDBServer *gdbserver, ssize_t index) -{ - WasmDebugPacket *pkt = &gdbserver->pkt; - memmove(pkt->buf, pkt->buf + index, pkt->size - index); - pkt->size -= index; -} - -void -inbuf_erase_head(WASMGDBServer *gdbserver, ssize_t index) -{ - pktbuf_erase_head(gdbserver, index); -} - -void -pktbuf_clear(WASMGDBServer *gdbserver) -{ - WasmDebugPacket *pkt = &gdbserver->pkt; - pkt->size = 0; -} - -int32 -read_data_once(WASMGDBServer *gdbserver) -{ - ssize_t nread; - uint8 buf[4096]; - - nread = os_socket_recv(gdbserver->socket_fd, buf, sizeof(buf)); - if (nread <= 0) { - LOG_ERROR("Connection closed"); - return -1; - } - pktbuf_insert(gdbserver, buf, nread); - return nread; -} - void write_data_raw(WASMGDBServer *gdbserver, const uint8 *data, ssize_t len) { @@ -139,40 +89,3 @@ write_binary_packet(WASMGDBServer *gdbserver, const char *pfx, write_packet_bytes(gdbserver, buf, buf_num_bytes); wasm_runtime_free(buf); } - -bool -skip_to_packet_start(WASMGDBServer *gdbserver) -{ - ssize_t start_index = -1, i; - - for (i = 0; i < (ssize_t)gdbserver->pkt.size; ++i) { - if (gdbserver->pkt.buf[i] == '$') { - start_index = i; - break; - } - } - - if (start_index < 0) { - pktbuf_clear(gdbserver); - return false; - } - - pktbuf_erase_head(gdbserver, start_index); - - bh_assert(1 <= gdbserver->pkt.size); - bh_assert('$' == gdbserver->pkt.buf[0]); - - return true; -} - -bool -read_packet(WASMGDBServer *gdbserver) -{ - while (!skip_to_packet_start(gdbserver)) { - if (read_data_once(gdbserver) < 0) - return false; - } - if (!gdbserver->noack) - write_data_raw(gdbserver, (uint8 *)"+", 1); - return true; -} diff --git a/core/iwasm/libraries/debug-engine/packets.h b/core/iwasm/libraries/debug-engine/packets.h index 5287d4794a..b35889394f 100644 --- a/core/iwasm/libraries/debug-engine/packets.h +++ b/core/iwasm/libraries/debug-engine/packets.h @@ -11,13 +11,7 @@ void write_data_raw(WASMGDBServer *gdbserver, const uint8 *data, ssize_t len); -bool -read_packet(WASMGDBServer *gdbserver); - void write_packet(WASMGDBServer *gdbserver, const char *data); -void -inbuf_erase_head(WASMGDBServer *gdbserver, ssize_t end); - #endif From 934bf6a5f1af79376a011c464741b012d55f7683 Mon Sep 17 00:00:00 2001 From: Xu Jun <693788454@qq.com> Date: Thu, 27 Jan 2022 22:20:06 +0800 Subject: [PATCH 07/16] remove unnecessary comment --- core/iwasm/libraries/debug-engine/gdbserver.c | 1 - 1 file changed, 1 deletion(-) diff --git a/core/iwasm/libraries/debug-engine/gdbserver.c b/core/iwasm/libraries/debug-engine/gdbserver.c index e91ac828b3..c97493efdd 100644 --- a/core/iwasm/libraries/debug-engine/gdbserver.c +++ b/core/iwasm/libraries/debug-engine/gdbserver.c @@ -280,7 +280,6 @@ wasm_gdbserver_handle_packet(WASMGDBServer *server) process_packet(server); } else if (ret == 2) { - LOG_VERBOSE("Received interrupt package"); handle_interrupt(server); } } From 5fafce80ff885fd4feb4d23f1dfb5724d10052b4 Mon Sep 17 00:00:00 2001 From: Xu Jun <693788454@qq.com> Date: Thu, 27 Jan 2022 22:24:06 +0800 Subject: [PATCH 08/16] add empty line between type declaration --- core/iwasm/libraries/debug-engine/gdbserver.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/iwasm/libraries/debug-engine/gdbserver.h b/core/iwasm/libraries/debug-engine/gdbserver.h index fc17fb8000..98ff834350 100644 --- a/core/iwasm/libraries/debug-engine/gdbserver.h +++ b/core/iwasm/libraries/debug-engine/gdbserver.h @@ -18,6 +18,7 @@ enum GDBStoppointType { eWatchpointRead, eWatchpointReadWrite }; + typedef enum rsp_recv_phase_t { Phase_Idle, Phase_Payload, @@ -33,6 +34,7 @@ typedef struct rsp_recv_context_t { /* RSP packet should not be too long */ char receive_buffer[1024]; } rsp_recv_context_t; + typedef struct WasmDebugPacket { unsigned char buf[PACKET_BUF_SIZE]; uint32 size; From cbaebb65c5cf05b3d2329c48acf534a4bc4133bc Mon Sep 17 00:00:00 2001 From: Xu Jun <693788454@qq.com> Date: Thu, 27 Jan 2022 22:45:52 +0800 Subject: [PATCH 09/16] fix some warning on windows --- core/iwasm/libraries/debug-engine/debug_engine.c | 3 ++- core/iwasm/libraries/debug-engine/handler.c | 2 +- core/shared/platform/windows/win_socket.c | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/core/iwasm/libraries/debug-engine/debug_engine.c b/core/iwasm/libraries/debug-engine/debug_engine.c index 750359d540..6095f91788 100644 --- a/core/iwasm/libraries/debug-engine/debug_engine.c +++ b/core/iwasm/libraries/debug-engine/debug_engine.c @@ -119,7 +119,8 @@ control_thread_routine(void *arg) korp_tid tid; status = - debug_inst->stopped_thread->current_status->signal_flag; + (uint32) + debug_inst->stopped_thread->current_status->signal_flag; tid = debug_inst->stopped_thread->handle; if (debug_inst->stopped_thread->current_status->running_status diff --git a/core/iwasm/libraries/debug-engine/handler.c b/core/iwasm/libraries/debug-engine/handler.c index 0cbadb52fb..e2df10ab76 100644 --- a/core/iwasm/libraries/debug-engine/handler.c +++ b/core/iwasm/libraries/debug-engine/handler.c @@ -455,7 +455,7 @@ handle_threadstop_request(WASMGDBServer *server, char *payload) } tid = debug_inst->stopped_thread->handle; - status = debug_inst->stopped_thread->current_status->signal_flag; + status = (uint32)debug_inst->stopped_thread->current_status->signal_flag; wasm_debug_instance_set_cur_thread(debug_inst, tid); diff --git a/core/shared/platform/windows/win_socket.c b/core/shared/platform/windows/win_socket.c index e71063481d..baa0eb8b14 100644 --- a/core/shared/platform/windows/win_socket.c +++ b/core/shared/platform/windows/win_socket.c @@ -88,7 +88,7 @@ os_socket_bind(bh_socket_t socket, const char *host, int *port) int os_socket_settimeout(bh_socket_t socket, unsigned long long int timeout_us) { - DWORD tv = timeout_us / 1000UL; + DWORD tv = (DWORD)(timeout_us / 1000UL); if (setsockopt(socket, SOL_SOCKET, SO_RCVTIMEO, (const char *)&tv, sizeof(tv)) From 492f5d567fd499dcd4276055c0eda0be5279d9ae Mon Sep 17 00:00:00 2001 From: Xu Jun <693788454@qq.com> Date: Thu, 27 Jan 2022 23:26:48 +0800 Subject: [PATCH 10/16] enable windows platform --- core/iwasm/libraries/debug-engine/gdbserver.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/core/iwasm/libraries/debug-engine/gdbserver.c b/core/iwasm/libraries/debug-engine/gdbserver.c index c97493efdd..f1451affa6 100644 --- a/core/iwasm/libraries/debug-engine/gdbserver.c +++ b/core/iwasm/libraries/debug-engine/gdbserver.c @@ -258,7 +258,12 @@ wasm_gdbserver_handle_packet(WASMGDBServer *server) return false; } else if (n < 0) { - if (errno == EAGAIN || errno == EWOULDBLOCK) { +#if defined(BH_PLATFORM_WINDOWS) + if (WSAGetLastError() == WSAETIMEDOUT) +#else + if (errno == EAGAIN || errno == EWOULDBLOCK) +#endif + { /* No bytes arrived */ return true; } From 80219a667e73522c6f0ccfe6109b5a00f75e1146 Mon Sep 17 00:00:00 2001 From: Xu Jun <693788454@qq.com> Date: Fri, 28 Jan 2022 20:31:35 +0800 Subject: [PATCH 11/16] enhance cmake option check --- build-scripts/runtime_lib.cmake | 8 +++++++- core/shared/platform/common/posix/posix_socket.c | 2 +- core/shared/platform/include/platform_api_extension.h | 2 +- core/shared/platform/windows/win_socket.c | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/build-scripts/runtime_lib.cmake b/build-scripts/runtime_lib.cmake index 513a0a6c2b..e7f7860cfc 100644 --- a/build-scripts/runtime_lib.cmake +++ b/build-scripts/runtime_lib.cmake @@ -87,6 +87,12 @@ endif () if (WAMR_BUILD_DEBUG_INTERP EQUAL 1) set (WAMR_BUILD_THREAD_MGR 1) include (${IWASM_DIR}/libraries/debug-engine/debug_engine.cmake) + + if (WAMR_BUILD_FAST_INTERP EQUAL 1) + set (WAMR_BUILD_FAST_INTERP 0) + message(STATUS + "Debugger doesn't work with fast interpreter, switch to classic interpreter") + endif () endif () if (WAMR_BUILD_THREAD_MGR EQUAL 1) @@ -95,7 +101,7 @@ endif () if (WAMR_BUILD_LIBC_EMCC EQUAL 1) include (${IWASM_DIR}/libraries/libc-emcc/libc_emcc.cmake) -endif() +endif () ####################### Common sources ####################### if (NOT MSVC) diff --git a/core/shared/platform/common/posix/posix_socket.c b/core/shared/platform/common/posix/posix_socket.c index fd325a4f83..0f7e8fcaea 100644 --- a/core/shared/platform/common/posix/posix_socket.c +++ b/core/shared/platform/common/posix/posix_socket.c @@ -72,7 +72,7 @@ os_socket_bind(bh_socket_t socket, const char *host, int *port) } int -os_socket_settimeout(bh_socket_t socket, unsigned long long int timeout_us) +os_socket_settimeout(bh_socket_t socket, uint64 timeout_us) { struct timeval tv; tv.tv_sec = timeout_us / 1000000UL; diff --git a/core/shared/platform/include/platform_api_extension.h b/core/shared/platform/include/platform_api_extension.h index 2ee5c67a2d..937882ca95 100644 --- a/core/shared/platform/include/platform_api_extension.h +++ b/core/shared/platform/include/platform_api_extension.h @@ -235,7 +235,7 @@ os_socket_bind(bh_socket_t socket, const char *addr, int *port); * @return 0 if success, -1 otherwise */ int -os_socket_settimeout(bh_socket_t socket, unsigned long long int timeout_us); +os_socket_settimeout(bh_socket_t socket, uint64 timeout_us); /** * Make the socket as a passive socket to accept incoming connection requests diff --git a/core/shared/platform/windows/win_socket.c b/core/shared/platform/windows/win_socket.c index baa0eb8b14..512d50280e 100644 --- a/core/shared/platform/windows/win_socket.c +++ b/core/shared/platform/windows/win_socket.c @@ -86,7 +86,7 @@ os_socket_bind(bh_socket_t socket, const char *host, int *port) } int -os_socket_settimeout(bh_socket_t socket, unsigned long long int timeout_us) +os_socket_settimeout(bh_socket_t socket, uint64 timeout_us) { DWORD tv = (DWORD)(timeout_us / 1000UL); From ba83116abb40b9357185cad2c083bb2d85e2f69e Mon Sep 17 00:00:00 2001 From: Xu Jun <693788454@qq.com> Date: Fri, 4 Feb 2022 17:34:55 +0800 Subject: [PATCH 12/16] change vendor string --- core/iwasm/libraries/debug-engine/handler.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/core/iwasm/libraries/debug-engine/handler.c b/core/iwasm/libraries/debug-engine/handler.c index e2df10ab76..7799ea8f5c 100644 --- a/core/iwasm/libraries/debug-engine/handler.c +++ b/core/iwasm/libraries/debug-engine/handler.c @@ -192,12 +192,11 @@ handle_generay_query(WASMGDBServer *server, char *payload) } if (!strcmp(name, "HostInfo")) { - // Todo: change vendor to Intel for outside tree? - mem2hex("wasm32-Ant-wasi-wasm", triple, strlen("wasm32-Ant-wasi-wasm")); + mem2hex("wasm32-wamr-wasi-wasm", triple, strlen("wasm32-wamr-wasi-wasm")); os_mutex_lock(&tmpbuf_lock); snprintf(tmpbuf, sizeof(tmpbuf), - "vendor:Ant;ostype:wasi;arch:wasm32;" + "vendor:wamr;ostype:wasi;arch:wasm32;" "triple:%s;endian:little;ptrsize:4;", triple); write_packet(server, tmpbuf); @@ -223,13 +222,12 @@ handle_generay_query(WASMGDBServer *server, char *payload) uint64 pid; pid = wasm_debug_instance_get_pid( (WASMDebugInstance *)server->thread->debug_instance); - // arch-vendor-os-env(format) - mem2hex("wasm32-Ant-wasi-wasm", triple, strlen("wasm32-Ant-wasi-wasm")); + mem2hex("wasm32-wamr-wasi-wasm", triple, strlen("wasm32-wamr-wasi-wasm")); os_mutex_lock(&tmpbuf_lock); snprintf(tmpbuf, sizeof(tmpbuf), "pid:%" PRIx64 ";parent-pid:%" PRIx64 - ";vendor:Ant;ostype:wasi;arch:wasm32;" + ";vendor:wamr;ostype:wasi;arch:wasm32;" "triple:%s;endian:little;ptrsize:4;", pid, pid, triple); write_packet(server, tmpbuf); From f226bed5bab499fe8c0fe2979ad1bf1fdd28b91b Mon Sep 17 00:00:00 2001 From: Xu Jun <693788454@qq.com> Date: Fri, 4 Feb 2022 17:37:35 +0800 Subject: [PATCH 13/16] auto format --- core/iwasm/libraries/debug-engine/handler.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/core/iwasm/libraries/debug-engine/handler.c b/core/iwasm/libraries/debug-engine/handler.c index 7799ea8f5c..29f37f61d1 100644 --- a/core/iwasm/libraries/debug-engine/handler.c +++ b/core/iwasm/libraries/debug-engine/handler.c @@ -192,7 +192,8 @@ handle_generay_query(WASMGDBServer *server, char *payload) } if (!strcmp(name, "HostInfo")) { - mem2hex("wasm32-wamr-wasi-wasm", triple, strlen("wasm32-wamr-wasi-wasm")); + mem2hex("wasm32-wamr-wasi-wasm", triple, + strlen("wasm32-wamr-wasi-wasm")); os_mutex_lock(&tmpbuf_lock); snprintf(tmpbuf, sizeof(tmpbuf), @@ -222,7 +223,8 @@ handle_generay_query(WASMGDBServer *server, char *payload) uint64 pid; pid = wasm_debug_instance_get_pid( (WASMDebugInstance *)server->thread->debug_instance); - mem2hex("wasm32-wamr-wasi-wasm", triple, strlen("wasm32-wamr-wasi-wasm")); + mem2hex("wasm32-wamr-wasi-wasm", triple, + strlen("wasm32-wamr-wasi-wasm")); os_mutex_lock(&tmpbuf_lock); snprintf(tmpbuf, sizeof(tmpbuf), From f4c6f10c6c3d3e37c56cb49f52fe136ee4898faa Mon Sep 17 00:00:00 2001 From: Xu Jun <693788454@qq.com> Date: Tue, 15 Feb 2022 14:18:00 +0800 Subject: [PATCH 14/16] address PR comments --- .../libraries/debug-engine/debug_engine.c | 21 ++++++++++++++++--- core/iwasm/libraries/debug-engine/gdbserver.c | 5 +++-- core/iwasm/libraries/debug-engine/handler.c | 3 +++ .../libraries/thread-mgr/thread_manager.c | 2 ++ 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/core/iwasm/libraries/debug-engine/debug_engine.c b/core/iwasm/libraries/debug-engine/debug_engine.c index 6095f91788..6fc0cd37bc 100644 --- a/core/iwasm/libraries/debug-engine/debug_engine.c +++ b/core/iwasm/libraries/debug-engine/debug_engine.c @@ -29,6 +29,12 @@ on_thread_stop_event(WASMDebugInstance *debug_inst, WASMExecEnv *exec_env) { os_mutex_lock(&debug_inst->wait_lock); debug_inst->stopped_thread = exec_env; + + if (debug_inst->current_state == DBG_LAUNCHING) { + /* In launching phase, send a signal so that handle_threadstop_request + * can be woken up */ + os_cond_signal(&debug_inst->wait_cond); + } os_mutex_unlock(&debug_inst->wait_lock); } @@ -129,11 +135,13 @@ control_thread_routine(void *arg) * in the cluster, otherwise ignore this event */ status = 0; - /* By design, all the other threads should stopped at this - * moment, so it is safe to access the exec_env_list.len - * without lock */ + /* By design, all the other threads should have been stopped + * at this moment, so it is safe to access the + * exec_env_list.len without lock */ if (debug_inst->cluster->exec_env_list.len != 1) { debug_inst->stopped_thread = NULL; + /* The exiting thread may wait for the signal */ + os_cond_signal(&debug_inst->wait_cond); os_mutex_unlock(&control_thread->wait_lock); continue; } @@ -146,6 +154,11 @@ control_thread_routine(void *arg) debug_inst->current_state = APP_STOPPED; debug_inst->stopped_thread = NULL; + + if (status == 0) { + /* The exiting thread may wait for the signal */ + os_cond_signal(&debug_inst->wait_cond); + } } /* Processing incoming requests */ @@ -997,8 +1010,10 @@ wasm_debug_instance_kill(WASMDebugInstance *instance) wasm_cluster_thread_send_signal(exec_env, WAMR_SIG_TERM); if (instance->current_state == APP_STOPPED) { /* Resume all threads so they can receive the TERM signal */ + os_mutex_lock(&exec_env->wait_lock); exec_env->current_status->running_status = STATUS_RUNNING; os_cond_signal(&exec_env->wait_cond); + os_mutex_unlock(&exec_env->wait_lock); } exec_env = bh_list_elem_next(exec_env); } diff --git a/core/iwasm/libraries/debug-engine/gdbserver.c b/core/iwasm/libraries/debug-engine/gdbserver.c index f1451affa6..affd6c2e1f 100644 --- a/core/iwasm/libraries/debug-engine/gdbserver.c +++ b/core/iwasm/libraries/debug-engine/gdbserver.c @@ -132,7 +132,7 @@ wasm_close_gdbserver(WASMGDBServer *server) } static inline void -handler_packet(WASMGDBServer *server, char request, char *payload) +handle_packet(WASMGDBServer *server, char request, char *payload) { if (packet_handler_table[(int)request].handler != NULL) packet_handler_table[(int)request].handler(server, payload); @@ -149,7 +149,7 @@ process_packet(WASMGDBServer *server) payload = (char *)&inbuf[1]; LOG_VERBOSE("receive request:%c %s\n", request, payload); - handler_packet(server, request, payload); + handle_packet(server, request, payload); } static inline void @@ -158,6 +158,7 @@ push_byte(rsp_recv_context_t *ctx, unsigned char ch, bool checksum) if (ctx->receive_index >= sizeof(ctx->receive_buffer)) { LOG_ERROR("RSP message buffer overflow"); bh_assert(false); + return; } ctx->receive_buffer[ctx->receive_index++] = ch; diff --git a/core/iwasm/libraries/debug-engine/handler.c b/core/iwasm/libraries/debug-engine/handler.c index 29f37f61d1..d39bb35b9f 100644 --- a/core/iwasm/libraries/debug-engine/handler.c +++ b/core/iwasm/libraries/debug-engine/handler.c @@ -451,8 +451,11 @@ handle_threadstop_request(WASMGDBServer *server, char *payload) bh_assert(debug_inst->current_state == DBG_LAUNCHING); /* Waiting for the stop event */ + os_mutex_lock(&debug_inst->wait_lock); while (!debug_inst->stopped_thread) { + os_cond_wait(&debug_inst->wait_cond, &debug_inst->wait_lock); } + os_mutex_unlock(&debug_inst->wait_lock); tid = debug_inst->stopped_thread->handle; status = (uint32)debug_inst->stopped_thread->current_status->signal_flag; diff --git a/core/iwasm/libraries/thread-mgr/thread_manager.c b/core/iwasm/libraries/thread-mgr/thread_manager.c index 0d83fdcbf7..0a25c11b4a 100644 --- a/core/iwasm/libraries/thread-mgr/thread_manager.c +++ b/core/iwasm/libraries/thread-mgr/thread_manager.c @@ -293,6 +293,8 @@ wasm_cluster_del_exec_env(WASMCluster *cluster, WASMExecEnv *exec_env) other threads can't fire stop events */ os_mutex_lock(&cluster->debug_inst->wait_lock); while (cluster->debug_inst->stopped_thread == exec_env) { + os_cond_wait(&cluster->debug_inst->wait_cond, + &cluster->debug_inst->wait_lock); } os_mutex_unlock(&cluster->debug_inst->wait_lock); } From 7aceef75b1a28f12fb1a03a22823bb0b06cca976 Mon Sep 17 00:00:00 2001 From: Xu Jun <693788454@qq.com> Date: Tue, 15 Feb 2022 14:22:23 +0800 Subject: [PATCH 15/16] ignore empty gdb request --- core/iwasm/libraries/debug-engine/gdbserver.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/core/iwasm/libraries/debug-engine/gdbserver.c b/core/iwasm/libraries/debug-engine/gdbserver.c index affd6c2e1f..788353fd46 100644 --- a/core/iwasm/libraries/debug-engine/gdbserver.c +++ b/core/iwasm/libraries/debug-engine/gdbserver.c @@ -148,6 +148,11 @@ process_packet(WASMGDBServer *server) request = inbuf[0]; payload = (char *)&inbuf[1]; + if (request == '\0') { + LOG_VERBOSE("ignore empty request"); + return; + } + LOG_VERBOSE("receive request:%c %s\n", request, payload); handle_packet(server, request, payload); } From a5ab4dd3c7ae68a8a3344b754da8b07b653be5e9 Mon Sep 17 00:00:00 2001 From: Xu Jun <693788454@qq.com> Date: Wed, 16 Feb 2022 13:56:42 +0800 Subject: [PATCH 16/16] address PR comment --- core/iwasm/libraries/debug-engine/gdbserver.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/core/iwasm/libraries/debug-engine/gdbserver.c b/core/iwasm/libraries/debug-engine/gdbserver.c index 788353fd46..98f8aa2754 100644 --- a/core/iwasm/libraries/debug-engine/gdbserver.c +++ b/core/iwasm/libraries/debug-engine/gdbserver.c @@ -146,13 +146,14 @@ process_packet(WASMGDBServer *server) char *payload = NULL; request = inbuf[0]; - payload = (char *)&inbuf[1]; if (request == '\0') { LOG_VERBOSE("ignore empty request"); return; } + payload = (char *)&inbuf[1]; + LOG_VERBOSE("receive request:%c %s\n", request, payload); handle_packet(server, request, payload); }