Explorar o código

Enable source debugging feature for windows platform (#910)

- use platform independent data types in debug-engine library
- add os_socket APIs and provide windows and posix implementation
- avoid using platform related header files in non-platform layer
- use format specifiers macros for sprintf and sscanf
- change thread handle type from uint64 to korp_tid
- add lock when sending socket packet to avoid thread racing
Xu Jun %!s(int64=4) %!d(string=hai) anos
pai
achega
ccb2de35d7

+ 72 - 52
core/iwasm/libraries/debug-engine/debug_engine.c

@@ -4,9 +4,8 @@
  */
 
 #include "debug_engine.h"
-
-#include "bh_log.h"
 #include "gdbserver.h"
+#include "handler.h"
 #include "bh_platform.h"
 #include "wasm_interp.h"
 #include "wasm_opcode.h"
@@ -18,8 +17,8 @@ typedef struct WASMDebugEngine {
     struct WASMDebugEngine *next;
     WASMDebugControlThread *control_thread;
     char ip_addr[128];
-    int platform_port;
-    int process_base_port;
+    int32 platform_port;
+    int32 process_base_port;
     bh_list debug_instance_list;
     korp_mutex instance_list_lock;
     bool active;
@@ -66,7 +65,8 @@ control_thread_routine(void *arg)
 
     control_thread->debug_engine = g_debug_engine;
     control_thread->debug_instance = debug_inst;
-    strcpy(control_thread->ip_addr, g_debug_engine->ip_addr);
+    bh_strcpy_s(control_thread->ip_addr, sizeof(control_thread->ip_addr),
+                g_debug_engine->ip_addr);
     control_thread->port =
         (g_debug_engine->process_base_port == 0)
             ? 0
@@ -171,6 +171,7 @@ static void
 wasm_debug_control_thread_destroy(WASMDebugInstance *debug_instance)
 {
     WASMDebugControlThread *control_thread = debug_instance->control_thread;
+
     LOG_VERBOSE("stopping control thread of debug object [%p]\n",
                 debug_instance);
     control_thread->status = STOPPED;
@@ -222,6 +223,7 @@ void
 wasm_debug_engine_destroy()
 {
     if (g_debug_engine) {
+        wasm_debug_handler_deinit();
         os_mutex_destroy(&g_debug_engine->instance_list_lock);
         wasm_runtime_free(g_debug_engine);
         g_debug_engine = NULL;
@@ -229,10 +231,15 @@ wasm_debug_engine_destroy()
 }
 
 bool
-wasm_debug_engine_init(char *ip_addr, int platform_port, int process_port)
+wasm_debug_engine_init(char *ip_addr, int32 platform_port, int32 process_port)
 {
-    if (g_debug_engine == NULL)
+    if (wasm_debug_handler_init() != 0) {
+        return false;
+    }
+
+    if (g_debug_engine == NULL) {
         g_debug_engine = wasm_debug_engine_create();
+    }
 
     if (g_debug_engine) {
         process_port -= 1;
@@ -241,11 +248,16 @@ wasm_debug_engine_init(char *ip_addr, int platform_port, int process_port)
         g_debug_engine->process_base_port =
             (process_port > 0) ? process_port : 0;
         if (ip_addr)
-            sprintf(g_debug_engine->ip_addr, "%s", ip_addr);
+            snprintf(g_debug_engine->ip_addr, sizeof(g_debug_engine->ip_addr),
+                     "%s", ip_addr);
         else
-            sprintf(g_debug_engine->ip_addr, "%s", "127.0.0.1");
+            snprintf(g_debug_engine->ip_addr, sizeof(g_debug_engine->ip_addr),
+                     "%s", "127.0.0.1");
         g_debug_engine->active = true;
     }
+    else {
+        wasm_debug_handler_deinit();
+    }
 
     return g_debug_engine != NULL ? true : false;
 }
@@ -385,7 +397,7 @@ wasm_debug_instance_get_current_env(WASMDebugInstance *instance)
 #if WASM_ENABLE_LIBC_WASI != 0
 bool
 wasm_debug_instance_get_current_object_name(WASMDebugInstance *instance,
-                                            char name_buffer[], int len)
+                                            char name_buffer[], uint32 len)
 {
     WASMExecEnv *exec_env;
     WASIArguments *wasi_args;
@@ -402,12 +414,13 @@ wasm_debug_instance_get_current_object_name(WASMDebugInstance *instance,
     wasi_args = &module_inst->module->wasi_args;
     if (wasi_args && wasi_args->argc > 0) {
         char *argv_name = wasi_args->argv[0];
-        int name_len = strlen(argv_name);
+        uint32 name_len = (uint32)strlen(argv_name);
+
         printf("the module name is %s\n", argv_name);
         if (len - 1 >= name_len)
-            strcpy(name_buffer, argv_name);
+            bh_strcpy_s(name_buffer, len, argv_name);
         else
-            strcpy(name_buffer, argv_name + (name_len + 1 - len));
+            bh_strcpy_s(name_buffer, len, argv_name + (name_len + 1 - len));
         return true;
     }
     return false;
@@ -423,21 +436,21 @@ wasm_debug_instance_get_pid(WASMDebugInstance *instance)
     return (uint64)0;
 }
 
-uint64
+korp_tid
 wasm_debug_instance_get_tid(WASMDebugInstance *instance)
 {
     if (instance != NULL) {
-        return (uint64)instance->current_tid;
+        return instance->current_tid;
     }
-    return (uint64)0;
+    return (korp_tid)(uintptr_t)0;
 }
 
-int
-wasm_debug_instance_get_tids(WASMDebugInstance *instance, uint64 tids[],
-                             int len)
+uint32
+wasm_debug_instance_get_tids(WASMDebugInstance *instance, korp_tid tids[],
+                             uint32 len)
 {
     WASMExecEnv *exec_env;
-    int i = 0, threads_num = 0;
+    uint32 i = 0, threads_num = 0;
 
     if (!instance)
         return 0;
@@ -471,8 +484,8 @@ get_stopped_thread(WASMCluster *cluster)
     return NULL;
 }
 
-uint64
-wasm_debug_instance_wait_thread(WASMDebugInstance *instance, uint64 tid,
+korp_tid
+wasm_debug_instance_wait_thread(WASMDebugInstance *instance, korp_tid tid,
                                 uint32 *status)
 {
     WASMExecEnv *exec_env = NULL;
@@ -491,19 +504,19 @@ wasm_debug_instance_wait_thread(WASMDebugInstance *instance, uint64 tid,
     }
 
     instance->current_tid = exec_env->handle;
-    *status = exec_env->current_status->signal_flag;
+    *status = (uint32)exec_env->current_status->signal_flag;
     return exec_env->handle;
 }
 
 uint32
-wasm_debug_instance_get_thread_status(WASMDebugInstance *instance, uint64 tid)
+wasm_debug_instance_get_thread_status(WASMDebugInstance *instance, korp_tid tid)
 {
     WASMExecEnv *exec_env = NULL;
 
     exec_env = bh_list_first_elem(&instance->cluster->exec_env_list);
     while (exec_env) {
         if (exec_env->handle == tid) {
-            return exec_env->current_status->signal_flag;
+            return (uint32)exec_env->current_status->signal_flag;
         }
         exec_env = bh_list_elem_next(exec_env);
     }
@@ -512,7 +525,7 @@ wasm_debug_instance_get_thread_status(WASMDebugInstance *instance, uint64 tid)
 }
 
 void
-wasm_debug_instance_set_cur_thread(WASMDebugInstance *instance, uint64 tid)
+wasm_debug_instance_set_cur_thread(WASMDebugInstance *instance, korp_tid tid)
 {
     instance->current_tid = tid;
 }
@@ -586,8 +599,10 @@ wasm_debug_instance_get_memregion(WASMDebugInstance *instance, uint64 addr)
             if (WASM_ADDR_OFFSET(addr) < module_inst->module->load_size) {
                 mem_info->start = WASM_ADDR(WasmObj, instance->id, 0);
                 mem_info->size = module_inst->module->load_size;
-                sprintf(mem_info->name, "%s", "module");
-                sprintf(mem_info->permisson, "%s", "rx");
+                snprintf(mem_info->name, sizeof(mem_info->name), "%s",
+                         "module");
+                snprintf(mem_info->permisson, sizeof(mem_info->permisson), "%s",
+                         "rx");
             }
             break;
         case WasmMemory:
@@ -601,8 +616,10 @@ wasm_debug_instance_get_memregion(WASMDebugInstance *instance, uint64 addr)
             if (WASM_ADDR_OFFSET(addr) < linear_mem_size) {
                 mem_info->start = WASM_ADDR(WasmMemory, instance->id, 0);
                 mem_info->size = linear_mem_size;
-                sprintf(mem_info->name, "%s", "memory");
-                sprintf(mem_info->permisson, "%s", "rw");
+                snprintf(mem_info->name, sizeof(mem_info->name), "%s",
+                         "memory");
+                snprintf(mem_info->permisson, sizeof(mem_info->permisson), "%s",
+                         "rw");
             }
             break;
         }
@@ -626,6 +643,8 @@ wasm_debug_instance_get_obj_mem(WASMDebugInstance *instance, uint64 offset,
 {
     WASMExecEnv *exec_env;
     WASMModuleInstance *module_inst;
+    WASMDebugBreakPoint *breakpoint;
+    WASMFastOPCodeNode *fast_opcode;
 
     if (!instance)
         return false;
@@ -643,11 +662,10 @@ wasm_debug_instance_get_obj_mem(WASMDebugInstance *instance, uint64 offset,
                     : 0;
     }
 
-    bh_memcpy_s(buf, *size, module_inst->module->load_addr + offset, *size);
-
-    WASMDebugBreakPoint *breakpoint =
-        bh_list_first_elem(&instance->break_point_list);
+    bh_memcpy_s(buf, (uint32)*size, module_inst->module->load_addr + offset,
+                (uint32)*size);
 
+    breakpoint = bh_list_first_elem(&instance->break_point_list);
     while (breakpoint) {
         if (offset <= breakpoint->addr && breakpoint->addr < offset + *size) {
             bh_memcpy_s(buf + (breakpoint->addr - offset), sizeof(break_instr),
@@ -656,8 +674,7 @@ wasm_debug_instance_get_obj_mem(WASMDebugInstance *instance, uint64 offset,
         breakpoint = bh_list_elem_next(breakpoint);
     }
 
-    WASMFastOPCodeNode *fast_opcode =
-        bh_list_first_elem(&module_inst->module->fast_opcode_list);
+    fast_opcode = bh_list_first_elem(&module_inst->module->fast_opcode_list);
     while (fast_opcode) {
         if (offset <= fast_opcode->offset
             && fast_opcode->offset < offset + *size) {
@@ -696,7 +713,8 @@ wasm_debug_instance_get_linear_mem(WASMDebugInstance *instance, uint64 offset,
             LOG_VERBOSE("wasm_debug_instance_get_linear_mem size over flow!\n");
             *size = linear_mem_size >= offset ? linear_mem_size - offset : 0;
         }
-        bh_memcpy_s(buf, *size, memory->memory_data + offset, *size);
+        bh_memcpy_s(buf, (uint32)*size, memory->memory_data + offset,
+                    (uint32)*size);
         return true;
     }
     return false;
@@ -728,7 +746,8 @@ wasm_debug_instance_set_linear_mem(WASMDebugInstance *instance, uint64 offset,
             LOG_VERBOSE("wasm_debug_instance_get_linear_mem size over flow!\n");
             *size = linear_mem_size >= offset ? linear_mem_size - offset : 0;
         }
-        bh_memcpy_s(memory->memory_data + offset, *size, buf, *size);
+        bh_memcpy_s(memory->memory_data + offset, (uint32)*size, buf,
+                    (uint32)*size);
         return true;
     }
     return false;
@@ -785,13 +804,13 @@ wasm_exec_env_get_instance(WASMExecEnv *exec_env)
     return instance;
 }
 
-int
-wasm_debug_instance_get_call_stack_pcs(WASMDebugInstance *instance, uint64 tid,
-                                       uint64 buf[], uint64 size)
+uint32
+wasm_debug_instance_get_call_stack_pcs(WASMDebugInstance *instance,
+                                       korp_tid tid, uint64 buf[], uint64 size)
 {
     WASMExecEnv *exec_env;
     struct WASMInterpFrame *frame;
-    uint64 i = 0;
+    uint32 i = 0;
 
     if (!instance)
         return 0;
@@ -948,7 +967,7 @@ wasm_debug_instance_kill(WASMDebugInstance *instance)
 }
 
 bool
-wasm_debug_instance_singlestep(WASMDebugInstance *instance, uint64 tid)
+wasm_debug_instance_singlestep(WASMDebugInstance *instance, korp_tid tid)
 {
     WASMExecEnv *exec_env;
 
@@ -960,7 +979,7 @@ wasm_debug_instance_singlestep(WASMDebugInstance *instance, uint64 tid)
         return false;
 
     while (exec_env) {
-        if (exec_env->handle == tid || tid == (uint64)~0) {
+        if (exec_env->handle == tid || tid == (korp_tid)(uintptr_t)~0LL) {
             wasm_cluster_thread_send_signal(exec_env, WAMR_SIG_SINGSTEP);
             wasm_cluster_thread_step(exec_env);
         }
@@ -970,16 +989,16 @@ wasm_debug_instance_singlestep(WASMDebugInstance *instance, uint64 tid)
 }
 
 bool
-wasm_debug_instance_get_local(WASMDebugInstance *instance, int frame_index,
-                              int local_index, char buf[], int *size)
+wasm_debug_instance_get_local(WASMDebugInstance *instance, int32 frame_index,
+                              int32 local_index, char buf[], int32 *size)
 {
     WASMExecEnv *exec_env;
     struct WASMInterpFrame *frame;
     WASMFunctionInstance *cur_func;
     uint8 local_type = 0xFF;
     uint32 local_offset;
-    int param_count;
-    int fi = 0;
+    int32 param_count;
+    int32 fi = 0;
 
     if (!instance)
         return false;
@@ -1029,8 +1048,8 @@ wasm_debug_instance_get_local(WASMDebugInstance *instance, int frame_index,
 }
 
 bool
-wasm_debug_instance_get_global(WASMDebugInstance *instance, int frame_index,
-                               int global_index, char buf[], int *size)
+wasm_debug_instance_get_global(WASMDebugInstance *instance, int32 frame_index,
+                               int32 global_index, char buf[], int32 *size)
 {
     WASMExecEnv *exec_env;
     struct WASMInterpFrame *frame;
@@ -1039,7 +1058,7 @@ wasm_debug_instance_get_global(WASMDebugInstance *instance, int frame_index,
     uint8 *global_addr;
     uint8 global_type = 0xFF;
     uint8 *global_data;
-    int fi = 0;
+    int32 fi = 0;
 
     if (!instance)
         return false;
@@ -1095,7 +1114,8 @@ wasm_debug_instance_get_global(WASMDebugInstance *instance, int frame_index,
 }
 
 uint64
-wasm_debug_instance_mmap(WASMDebugInstance *instance, uint32 size, int map_port)
+wasm_debug_instance_mmap(WASMDebugInstance *instance, uint32 size,
+                         int32 map_port)
 {
     WASMExecEnv *exec_env;
     WASMModuleInstance *module_inst;

+ 20 - 19
core/iwasm/libraries/debug-engine/debug_engine.h

@@ -87,7 +87,7 @@ WASMDebugInstance *
 wasm_exec_env_get_instance(WASMExecEnv *exec_env);
 
 bool
-wasm_debug_engine_init(char *ip_addr, int platform_port, int process_port);
+wasm_debug_engine_init(char *ip_addr, int32 platform_port, int32 process_port);
 
 void
 wasm_debug_engine_destroy();
@@ -101,15 +101,15 @@ wasm_debug_get_engine_active(void);
 uint64
 wasm_debug_instance_get_pid(WASMDebugInstance *instance);
 
-uint64
+korp_tid
 wasm_debug_instance_get_tid(WASMDebugInstance *instance);
 
-int
-wasm_debug_instance_get_tids(WASMDebugInstance *instance, uint64 tids[],
-                             int len);
+uint32
+wasm_debug_instance_get_tids(WASMDebugInstance *instance, korp_tid tids[],
+                             uint32 len);
 
 void
-wasm_debug_instance_set_cur_thread(WASMDebugInstance *instance, uint64 tid);
+wasm_debug_instance_set_cur_thread(WASMDebugInstance *instance, korp_tid tid);
 
 uint64
 wasm_debug_instance_get_pc(WASMDebugInstance *instance);
@@ -140,9 +140,9 @@ bool
 wasm_debug_instance_set_mem(WASMDebugInstance *instance, uint64 addr, char *buf,
                             uint64 *size);
 
-int
-wasm_debug_instance_get_call_stack_pcs(WASMDebugInstance *instance, uint64 tid,
-                                       uint64 buf[], uint64 size);
+uint32
+wasm_debug_instance_get_call_stack_pcs(WASMDebugInstance *instance,
+                                       korp_tid tid, uint64 buf[], uint64 size);
 
 bool
 wasm_debug_instance_add_breakpoint(WASMDebugInstance *instance, uint64 addr,
@@ -158,33 +158,34 @@ wasm_debug_instance_continue(WASMDebugInstance *instance);
 bool
 wasm_debug_instance_kill(WASMDebugInstance *instance);
 
-uint64
-wasm_debug_instance_wait_thread(WASMDebugInstance *instance, uint64 tid,
+korp_tid
+wasm_debug_instance_wait_thread(WASMDebugInstance *instance, korp_tid tid,
                                 uint32 *status);
 
 uint32
-wasm_debug_instance_get_thread_status(WASMDebugInstance *instance, uint64 tid);
+wasm_debug_instance_get_thread_status(WASMDebugInstance *instance,
+                                      korp_tid tid);
 
 bool
-wasm_debug_instance_singlestep(WASMDebugInstance *instance, uint64 tid);
+wasm_debug_instance_singlestep(WASMDebugInstance *instance, korp_tid tid);
 
 bool
-wasm_debug_instance_get_local(WASMDebugInstance *instance, int frame_index,
-                              int local_index, char buf[], int *size);
+wasm_debug_instance_get_local(WASMDebugInstance *instance, int32 frame_index,
+                              int32 local_index, char buf[], int32 *size);
 
 bool
-wasm_debug_instance_get_global(WASMDebugInstance *instance, int frame_index,
-                               int global_index, char buf[], int *size);
+wasm_debug_instance_get_global(WASMDebugInstance *instance, int32 frame_index,
+                               int32 global_index, char buf[], int32 *size);
 
 #if WASM_ENABLE_LIBC_WASI != 0
 bool
 wasm_debug_instance_get_current_object_name(WASMDebugInstance *instance,
-                                            char name_buffer[], int len);
+                                            char name_buffer[], uint32 len);
 #endif
 
 uint64
 wasm_debug_instance_mmap(WASMDebugInstance *instance, uint32 size,
-                         int map_port);
+                         int32 map_port);
 
 bool
 wasm_debug_instance_ummap(WASMDebugInstance *instance, uint64 addr);

+ 35 - 80
core/iwasm/libraries/debug-engine/gdbserver.c

@@ -3,22 +3,8 @@
  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  */
 
+#include "bh_platform.h"
 #include "gdbserver.h"
-
-#include <arpa/inet.h>
-#include <fcntl.h>
-#include <netinet/in.h>
-#include <netinet/tcp.h>
-#include <signal.h>
-#include <stdbool.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/poll.h>
-#include <sys/socket.h>
-#include <unistd.h>
-
-#include "bh_log.h"
 #include "handler.h"
 #include "packets.h"
 #include "utils.h"
@@ -51,14 +37,9 @@ static struct packet_handler_elem packet_handler_table[255] = {
 };
 
 WASMGDBServer *
-wasm_create_gdbserver(char *host, int *port)
+wasm_create_gdbserver(const char *host, int32 *port)
 {
-    int listen_fd = -1;
-    const int one = 1;
-    struct sockaddr_in addr;
-    socklen_t socklen;
-    int ret;
-
+    bh_socket_t listen_fd = (bh_socket_t)-1;
     WASMGDBServer *server;
 
     bh_assert(port);
@@ -70,52 +51,25 @@ wasm_create_gdbserver(char *host, int *port)
 
     memset(server, 0, sizeof(WASMGDBServer));
 
-    listen_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
-    if (listen_fd < 0) {
-        LOG_ERROR("wasm gdb server error: socket() failed");
-        goto fail;
-    }
-
-    ret = fcntl(listen_fd, F_SETFD, FD_CLOEXEC);
-    if (ret < 0) {
-        LOG_ERROR(
-            "wasm gdb server error: fcntl() failed on setting FD_CLOEXEC");
-        goto fail;
-    }
-
-    ret = setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
-    if (ret < 0) {
-        LOG_ERROR("wasm gdb server error: setsockopt() failed");
-        goto fail;
-    }
-
-    addr.sin_family = AF_INET;
-    addr.sin_addr.s_addr = inet_addr(host);
-    addr.sin_port = htons(*port);
-
-    ret = bind(listen_fd, (struct sockaddr *)&addr, sizeof(addr));
-    if (ret < 0) {
-        LOG_ERROR("wasm gdb server error: bind() failed");
+    if (0 != os_socket_create(&listen_fd, 1)) {
+        LOG_ERROR("wasm gdb server error: create socket failed");
         goto fail;
     }
 
-    socklen = sizeof(addr);
-    if (getsockname(listen_fd, (void *)&addr, &socklen) == -1) {
-        LOG_ERROR("%s", strerror(errno));
+    if (0 != os_socket_bind(listen_fd, host, port)) {
+        LOG_ERROR("wasm gdb server error: socket bind failed");
         goto fail;
     }
-    LOG_WARNING("Debug server listening on %s:%d\n", host,
-                ntohs(addr.sin_port));
 
-    *port = ntohs(addr.sin_port);
+    LOG_WARNING("Debug server listening on %s:%" PRIu32 "\n", host, *port);
     server->listen_fd = listen_fd;
 
     return server;
 
 fail:
     if (listen_fd >= 0) {
-        shutdown(listen_fd, SHUT_RDWR);
-        close(listen_fd);
+        os_socket_shutdown(listen_fd);
+        os_socket_close(listen_fd);
     }
     if (server)
         wasm_runtime_free(server);
@@ -125,18 +79,18 @@ fail:
 bool
 wasm_gdbserver_listen(WASMGDBServer *server)
 {
-    int ret;
-    int sockt_fd = 0;
+    bh_socket_t sockt_fd = (bh_socket_t)-1;
+    int32 ret;
 
-    ret = listen(server->listen_fd, 1);
-    if (ret < 0) {
-        LOG_ERROR("wasm gdb server error: listen() failed");
+    ret = os_socket_listen(server->listen_fd, 1);
+    if (ret != 0) {
+        LOG_ERROR("wasm gdb server error: socket listen failed");
         goto fail;
     }
 
-    sockt_fd = accept(server->listen_fd, NULL, NULL);
+    os_socket_accept(server->listen_fd, &sockt_fd, NULL, NULL);
     if (sockt_fd < 0) {
-        LOG_ERROR("wasm gdb server error: accept() failed");
+        LOG_ERROR("wasm gdb server error: socket accept failed");
         goto fail;
     }
 
@@ -146,8 +100,8 @@ wasm_gdbserver_listen(WASMGDBServer *server)
     return true;
 
 fail:
-    shutdown(server->listen_fd, SHUT_RDWR);
-    close(server->listen_fd);
+    os_socket_shutdown(server->listen_fd);
+    os_socket_close(server->listen_fd);
     return false;
 }
 
@@ -155,12 +109,12 @@ void
 wasm_close_gdbserver(WASMGDBServer *server)
 {
     if (server->socket_fd > 0) {
-        shutdown(server->socket_fd, SHUT_RDWR);
-        close(server->socket_fd);
+        os_socket_shutdown(server->socket_fd);
+        os_socket_close(server->socket_fd);
     }
     if (server->listen_fd > 0) {
-        shutdown(server->listen_fd, SHUT_RDWR);
-        close(server->listen_fd);
+        os_socket_shutdown(server->listen_fd);
+        os_socket_close(server->listen_fd);
     }
 }
 
@@ -180,33 +134,34 @@ handler_packet(WASMGDBServer *server, char request, char *payload)
 static void
 process_packet(WASMGDBServer *server)
 {
-    uint8_t *inbuf = server->pkt.buf;
-    int inbuf_size = server->pkt.size;
-    uint8_t *packetend_ptr = (uint8_t *)memchr(inbuf, '#', inbuf_size);
-    int packetend = packetend_ptr - inbuf;
+    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_t checksum = 0;
+    uint8 checksum = 0;
 
-    if (packetend == 1) {
+    if (packet_size == 1) {
         LOG_VERBOSE("receive empty request, ignore it\n");
         return;
     }
 
     bh_assert('$' == inbuf[0]);
-    inbuf[packetend] = '\0';
+    inbuf[packet_size] = '\0';
 
-    for (int i = 1; i < packetend; i++)
+    for (int i = 1; i < packet_size; i++)
         checksum += inbuf[i];
-    bh_assert(checksum
-              == (hex(inbuf[packetend + 1]) << 4 | hex(inbuf[packetend + 2])));
+    bh_assert(
+        checksum
+        == (hex(inbuf[packet_size + 1]) << 4 | hex(inbuf[packet_size + 2])));
 
     payload = (char *)&inbuf[2];
 
     LOG_VERBOSE("receive request:%c %s\n", request, payload);
     handler_packet(server, request, payload);
 
-    inbuf_erase_head(server, packetend + 3);
+    inbuf_erase_head(server, packet_size + 3);
 }
 
 bool

+ 5 - 5
core/iwasm/libraries/debug-engine/gdbserver.h

@@ -6,7 +6,7 @@
 #ifndef _GDB_SERVER_H
 #define _GDB_SERVER_H
 
-#include <stdbool.h>
+#include "bh_platform.h"
 
 #define PACKET_BUF_SIZE 0x8000
 
@@ -20,20 +20,20 @@ enum GDBStoppointType {
 };
 typedef struct WasmDebugPacket {
     unsigned char buf[PACKET_BUF_SIZE];
-    unsigned int size;
+    uint32 size;
 } WasmDebugPacket;
 
 struct WASMDebugControlThread;
 typedef struct WASMGDBServer {
-    int listen_fd;
-    int socket_fd;
+    bh_socket_t listen_fd;
+    bh_socket_t socket_fd;
     WasmDebugPacket pkt;
     bool noack;
     struct WASMDebugControlThread *thread;
 } WASMGDBServer;
 
 WASMGDBServer *
-wasm_create_gdbserver(char *addr, int *port);
+wasm_create_gdbserver(const char *host, int32 *port);
 
 bool
 wasm_gdbserver_listen(WASMGDBServer *server);

+ 192 - 114
core/iwasm/libraries/debug-engine/handler.c

@@ -3,12 +3,8 @@
  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  */
 
-#include <bh_log.h>
-#include <handler.h>
-#include <limits.h>
-#include <string.h>
-#include <unistd.h>
-
+#include "bh_platform.h"
+#include "handler.h"
 #include "debug_engine.h"
 #include "packets.h"
 #include "utils.h"
@@ -16,9 +12,22 @@
 
 #define MAX_PACKET_SIZE (0x20000)
 static char tmpbuf[MAX_PACKET_SIZE];
+static korp_mutex tmpbuf_lock;
+
+int
+wasm_debug_handler_init()
+{
+    return os_mutex_init(&tmpbuf_lock);
+}
+
+void
+wasm_debug_handler_deinit()
+{
+    os_mutex_destroy(&tmpbuf_lock);
+}
 
 static void
-send_thread_stop_status(WASMGDBServer *server, uint32_t status, uint64_t tid);
+send_thread_stop_status(WASMGDBServer *server, uint32 status, korp_tid tid);
 
 void
 handle_generay_set(WASMGDBServer *server, char *payload)
@@ -59,37 +68,40 @@ process_xfer(WASMGDBServer *server, const char *name, char *args)
 
     if (!strcmp(name, "libraries") && !strcmp(mode, "read")) {
         // TODO: how to get current wasm file name?
-        uint64_t addr = wasm_debug_instance_get_load_addr(
+        uint64 addr = wasm_debug_instance_get_load_addr(
             (WASMDebugInstance *)server->thread->debug_instance);
+        os_mutex_lock(&tmpbuf_lock);
 #if WASM_ENABLE_LIBC_WASI != 0
         char objname[128];
         wasm_debug_instance_get_current_object_name(
             (WASMDebugInstance *)server->thread->debug_instance, objname, 128);
-        sprintf(tmpbuf,
-                "l<library-list><library name=\"%s\"><section "
-                "address=\"0x%lx\"/></library></library-list>",
-                objname, addr);
+        snprintf(tmpbuf, sizeof(tmpbuf),
+                 "l<library-list><library name=\"%s\"><section "
+                 "address=\"0x%" PRIx64 "\"/></library></library-list>",
+                 objname, addr);
 #else
-        sprintf(tmpbuf,
-                "l<library-list><library name=\"%s\"><section "
-                "address=\"0x%lx\"/></library></library-list>",
-                "nobody.wasm", addr);
+        snprintf(tmpbuf, sizeof(tmpbuf),
+                 "l<library-list><library name=\"%s\"><section "
+                 "address=\"0x%" PRIx64 "\"/></library></library-list>",
+                 "nobody.wasm", addr);
 #endif
         write_packet(server, tmpbuf);
+        os_mutex_unlock(&tmpbuf_lock);
     }
 }
 
 void
 porcess_wasm_local(WASMGDBServer *server, char *args)
 {
-    int frame_index;
-    int local_index;
+    int32 frame_index;
+    int32 local_index;
     char buf[16];
-    int size = 16;
+    int32 size = 16;
     bool ret;
 
-    sprintf(tmpbuf, "E01");
-    if (sscanf(args, "%d;%d", &frame_index, &local_index) == 2) {
+    os_mutex_lock(&tmpbuf_lock);
+    snprintf(tmpbuf, sizeof(tmpbuf), "E01");
+    if (sscanf(args, "%" PRId32 ";%" PRId32, &frame_index, &local_index) == 2) {
         ret = wasm_debug_instance_get_local(
             (WASMDebugInstance *)server->thread->debug_instance, frame_index,
             local_index, buf, &size);
@@ -98,19 +110,22 @@ porcess_wasm_local(WASMGDBServer *server, char *args)
         }
     }
     write_packet(server, tmpbuf);
+    os_mutex_unlock(&tmpbuf_lock);
 }
 
 void
 porcess_wasm_global(WASMGDBServer *server, char *args)
 {
-    int frame_index;
-    int global_index;
+    int32 frame_index;
+    int32 global_index;
     char buf[16];
-    int size = 16;
+    int32 size = 16;
     bool ret;
 
-    sprintf(tmpbuf, "E01");
-    if (sscanf(args, "%d;%d", &frame_index, &global_index) == 2) {
+    os_mutex_lock(&tmpbuf_lock);
+    snprintf(tmpbuf, sizeof(tmpbuf), "E01");
+    if (sscanf(args, "%" PRId32 ";%" PRId32, &frame_index, &global_index)
+        == 2) {
         ret = wasm_debug_instance_get_global(
             (WASMDebugInstance *)server->thread->debug_instance, frame_index,
             global_index, buf, &size);
@@ -119,6 +134,7 @@ porcess_wasm_global(WASMGDBServer *server, char *args)
         }
     }
     write_packet(server, tmpbuf);
+    os_mutex_unlock(&tmpbuf_lock);
 }
 
 void
@@ -126,6 +142,7 @@ handle_generay_query(WASMGDBServer *server, char *payload)
 {
     const char *name;
     char *args;
+    char triple[256];
 
     args = strchr(payload, ':');
     if (args)
@@ -134,18 +151,25 @@ handle_generay_query(WASMGDBServer *server, char *payload)
     LOG_VERBOSE("%s:%s\n", __FUNCTION__, payload);
 
     if (!strcmp(name, "C")) {
-        uint64_t pid, tid;
+        uint64 pid, tid;
         pid = wasm_debug_instance_get_pid(
             (WASMDebugInstance *)server->thread->debug_instance);
-        tid = wasm_debug_instance_get_tid(
+        tid = (uint64)(uintptr_t)wasm_debug_instance_get_tid(
             (WASMDebugInstance *)server->thread->debug_instance);
-        snprintf(tmpbuf, sizeof(tmpbuf), "QCp%lx.%lx", pid, tid);
+
+        os_mutex_lock(&tmpbuf_lock);
+        snprintf(tmpbuf, sizeof(tmpbuf), "QCp%" PRIx64 ".%" PRIx64 "", pid,
+                 tid);
         write_packet(server, tmpbuf);
+        os_mutex_unlock(&tmpbuf_lock);
     }
     if (!strcmp(name, "Supported")) {
-        sprintf(tmpbuf, "qXfer:libraries:read+;PacketSize=%x;",
-                MAX_PACKET_SIZE);
+        os_mutex_lock(&tmpbuf_lock);
+        snprintf(tmpbuf, sizeof(tmpbuf),
+                 "qXfer:libraries:read+;PacketSize=%" PRIx32 ";",
+                 MAX_PACKET_SIZE);
         write_packet(server, tmpbuf);
+        os_mutex_unlock(&tmpbuf_lock);
     }
 
     if (!strcmp(name, "Xfer")) {
@@ -166,21 +190,24 @@ handle_generay_query(WASMGDBServer *server, char *payload)
 
     if (!strcmp(name, "HostInfo")) {
         // Todo: change vendor to Intel for outside tree?
-        char triple[256];
         mem2hex("wasm32-Ant-wasi-wasm", triple, strlen("wasm32-Ant-wasi-wasm"));
-        sprintf(tmpbuf,
-                "vendor:Ant;ostype:wasi;arch:wasm32;"
-                "triple:%s;endian:little;ptrsize:4;",
-                triple);
 
+        os_mutex_lock(&tmpbuf_lock);
+        snprintf(tmpbuf, sizeof(tmpbuf),
+                 "vendor:Ant;ostype:wasi;arch:wasm32;"
+                 "triple:%s;endian:little;ptrsize:4;",
+                 triple);
         write_packet(server, tmpbuf);
+        os_mutex_unlock(&tmpbuf_lock);
     }
     if (!strcmp(name, "ModuleInfo")) {
         write_packet(server, "");
     }
     if (!strcmp(name, "GetWorkingDir")) {
+        os_mutex_lock(&tmpbuf_lock);
         if (getcwd(tmpbuf, PATH_MAX))
             write_packet(server, tmpbuf);
+        os_mutex_unlock(&tmpbuf_lock);
     }
     if (!strcmp(name, "QueryGDBServer")) {
         write_packet(server, "");
@@ -190,25 +217,29 @@ handle_generay_query(WASMGDBServer *server, char *payload)
     }
     if (!strcmp(name, "ProcessInfo")) {
         // Todo: process id parent-pid
-        uint64_t pid;
+        uint64 pid;
         pid = wasm_debug_instance_get_pid(
             (WASMDebugInstance *)server->thread->debug_instance);
-        char triple[256];
         // arch-vendor-os-env(format)
         mem2hex("wasm32-Ant-wasi-wasm", triple, strlen("wasm32-Ant-wasi-wasm"));
-        sprintf(tmpbuf,
-                "pid:%lx;parent-pid:%lx;vendor:Ant;ostype:wasi;arch:wasm32;"
-                "triple:%s;endian:little;ptrsize:4;",
-                pid, pid, triple);
 
+        os_mutex_lock(&tmpbuf_lock);
+        snprintf(tmpbuf, sizeof(tmpbuf),
+                 "pid:%" PRIx64 ";parent-pid:%" PRIx64
+                 ";vendor:Ant;ostype:wasi;arch:wasm32;"
+                 "triple:%s;endian:little;ptrsize:4;",
+                 pid, pid, triple);
         write_packet(server, tmpbuf);
+        os_mutex_unlock(&tmpbuf_lock);
     }
     if (!strcmp(name, "RegisterInfo0")) {
-        sprintf(
-            tmpbuf,
+        os_mutex_lock(&tmpbuf_lock);
+        snprintf(
+            tmpbuf, sizeof(tmpbuf),
             "name:pc;alt-name:pc;bitsize:64;offset:0;encoding:uint;format:hex;"
             "set:General Purpose Registers;gcc:16;dwarf:16;generic:pc;");
         write_packet(server, tmpbuf);
+        os_mutex_unlock(&tmpbuf_lock);
     }
     else if (!strncmp(name, "RegisterInfo", strlen("RegisterInfo"))) {
         write_packet(server, "E45");
@@ -218,16 +249,22 @@ handle_generay_query(WASMGDBServer *server, char *payload)
     }
 
     if (args && (!strcmp(name, "MemoryRegionInfo"))) {
-        uint64_t addr = strtol(args, NULL, 16);
+        uint64 addr = strtoll(args, NULL, 16);
         WASMDebugMemoryInfo *mem_info = wasm_debug_instance_get_memregion(
             (WASMDebugInstance *)server->thread->debug_instance, addr);
         if (mem_info) {
             char name_buf[256];
             mem2hex(mem_info->name, name_buf, strlen(mem_info->name));
-            sprintf(tmpbuf, "start:%lx;size:%lx;permissions:%s;name:%s;",
-                    (uint64)mem_info->start, mem_info->size,
-                    mem_info->permisson, name_buf);
+
+            os_mutex_lock(&tmpbuf_lock);
+            snprintf(tmpbuf, sizeof(tmpbuf),
+                     "start:%" PRIx64 ";size:%" PRIx64
+                     ";permissions:%s;name:%s;",
+                     (uint64)mem_info->start, mem_info->size,
+                     mem_info->permisson, name_buf);
             write_packet(server, tmpbuf);
+            os_mutex_unlock(&tmpbuf_lock);
+
             wasm_debug_instance_destroy_memregion(
                 (WASMDebugInstance *)server->thread->debug_instance, mem_info);
         }
@@ -244,14 +281,17 @@ handle_generay_query(WASMGDBServer *server, char *payload)
     }
 
     if (args && (!strcmp(name, "WasmCallStack"))) {
-        uint64_t tid = strtol(args, NULL, 16);
-        uint64_t buf[1024 / sizeof(uint64_t)];
-        uint64_t count = wasm_debug_instance_get_call_stack_pcs(
-            (WASMDebugInstance *)server->thread->debug_instance, tid, buf,
-            1024 / sizeof(uint64_t));
+        uint64 tid = strtoll(args, NULL, 16);
+        uint64 buf[1024 / sizeof(uint64)];
+        uint32 count = wasm_debug_instance_get_call_stack_pcs(
+            (WASMDebugInstance *)server->thread->debug_instance,
+            (korp_tid)(uintptr_t)tid, buf, 1024 / sizeof(uint64));
+
         if (count > 0) {
-            mem2hex((char *)buf, tmpbuf, count * sizeof(uint64_t));
+            os_mutex_lock(&tmpbuf_lock);
+            mem2hex((char *)buf, tmpbuf, count * sizeof(uint64));
             write_packet(server, tmpbuf);
+            os_mutex_unlock(&tmpbuf_lock);
         }
         else
             write_packet(server, "");
@@ -271,9 +311,11 @@ handle_generay_query(WASMGDBServer *server, char *payload)
 
     if (!strncmp(name, "ThreadStopInfo", strlen("ThreadStopInfo"))) {
         int32 prefix_len = strlen("ThreadStopInfo");
-        uint64 tid = strtol(name + prefix_len, NULL, 16);
+        uint64 tid_number = strtoll(name + prefix_len, NULL, 16);
+        korp_tid tid = (korp_tid)(uintptr_t)tid_number;
+        uint32 status;
 
-        uint32 status = wasm_debug_instance_get_thread_status(
+        status = wasm_debug_instance_get_thread_status(
             server->thread->debug_instance, tid);
 
         send_thread_stop_status(server, status, tid);
@@ -281,37 +323,44 @@ handle_generay_query(WASMGDBServer *server, char *payload)
 }
 
 static void
-send_thread_stop_status(WASMGDBServer *server, uint32_t status, uint64_t tid)
+send_thread_stop_status(WASMGDBServer *server, uint32 status, korp_tid tid)
 {
-    int tids_number, len = 0, i = 0;
-    uint64_t tids[20];
+    int32 len = 0;
+    uint64 pc;
+    korp_tid tids[20];
     char pc_string[17];
-    uint32_t gdb_status = status;
+    uint32 tids_count, i = 0;
+    uint32 gdb_status = status;
 
     if (status == 0) {
-        sprintf(tmpbuf, "W%02x", status);
+        os_mutex_lock(&tmpbuf_lock);
+        snprintf(tmpbuf, sizeof(tmpbuf), "W%02x", status);
         write_packet(server, tmpbuf);
+        os_mutex_unlock(&tmpbuf_lock);
         return;
     }
-    tids_number = wasm_debug_instance_get_tids(
+    tids_count = wasm_debug_instance_get_tids(
         (WASMDebugInstance *)server->thread->debug_instance, tids, 20);
-    uint64_t pc = wasm_debug_instance_get_pc(
+    pc = wasm_debug_instance_get_pc(
         (WASMDebugInstance *)server->thread->debug_instance);
 
     if (status == WAMR_SIG_SINGSTEP) {
         gdb_status = WAMR_SIG_TRAP;
     }
 
+    os_mutex_lock(&tmpbuf_lock);
     // TODO: how name a wasm thread?
-    len +=
-        sprintf(tmpbuf, "T%02xthread:%lx;name:%s;", gdb_status, tid, "nobody");
-    if (tids_number > 0) {
-        len += sprintf(tmpbuf + len, "threads:");
-        while (i < tids_number) {
-            if (i == tids_number - 1)
-                len += sprintf(tmpbuf + len, "%lx;", tids[i]);
+    len += snprintf(tmpbuf, sizeof(tmpbuf), "T%02xthread:%" PRIx64 ";name:%s;",
+                    gdb_status, (uint64)(uintptr_t)tid, "nobody");
+    if (tids_count > 0) {
+        len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len, "threads:");
+        while (i < tids_count) {
+            if (i == tids_count - 1)
+                len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len,
+                                "%" PRIx64 ";", (uint64)(uintptr_t)tids[i]);
             else
-                len += sprintf(tmpbuf + len, "%lx,", tids[i]);
+                len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len,
+                                "%" PRIx64 ",", (uint64)(uintptr_t)tids[i]);
             i++;
         }
     }
@@ -319,18 +368,22 @@ send_thread_stop_status(WASMGDBServer *server, uint32_t status, uint64_t tid)
     pc_string[8 * 2] = '\0';
 
     if (status == WAMR_SIG_TRAP) {
-        len += sprintf(tmpbuf + len, "thread-pcs:%lx;00:%s,reason:%s;", pc,
-                       pc_string, "breakpoint");
+        len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len,
+                        "thread-pcs:%" PRIx64 ";00:%s,reason:%s;", pc,
+                        pc_string, "breakpoint");
     }
     else if (status == WAMR_SIG_SINGSTEP) {
-        len += sprintf(tmpbuf + len, "thread-pcs:%lx;00:%s,reason:%s;", pc,
-                       pc_string, "trace");
+        len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len,
+                        "thread-pcs:%" PRIx64 ";00:%s,reason:%s;", pc,
+                        pc_string, "trace");
     }
     else if (status > 0) {
-        len += sprintf(tmpbuf + len, "thread-pcs:%lx;00:%s,reason:%s;", pc,
-                       pc_string, "signal");
+        len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len,
+                        "thread-pcs:%" PRIx64 ";00:%s,reason:%s;", pc,
+                        pc_string, "signal");
     }
     write_packet(server, tmpbuf);
+    os_mutex_unlock(&tmpbuf_lock);
 }
 
 void
@@ -338,7 +391,8 @@ handle_v_packet(WASMGDBServer *server, char *payload)
 {
     const char *name;
     char *args;
-    uint32_t status;
+    uint32 status;
+
     args = strchr(payload, ';');
     if (args)
         *args++ = '\0';
@@ -353,8 +407,12 @@ handle_v_packet(WASMGDBServer *server, char *payload)
             if (args[0] == 's' || args[0] == 'c') {
                 char *numstring = strchr(args, ':');
                 if (numstring) {
+                    uint64 tid_number;
+                    korp_tid tid;
+
                     *numstring++ = '\0';
-                    uint64_t tid = strtol(numstring, NULL, 16);
+                    tid_number = strtoll(numstring, NULL, 16);
+                    tid = (korp_tid)(uintptr_t)tid_number;
                     wasm_debug_instance_set_cur_thread(
                         (WASMDebugInstance *)server->thread->debug_instance,
                         tid);
@@ -383,9 +441,9 @@ handle_v_packet(WASMGDBServer *server, char *payload)
 void
 handle_threadstop_request(WASMGDBServer *server, char *payload)
 {
-    uint64_t tid = wasm_debug_instance_get_tid(
+    korp_tid tid = wasm_debug_instance_get_tid(
         (WASMDebugInstance *)server->thread->debug_instance);
-    uint32_t status;
+    uint32 status;
 
     tid = wasm_debug_instance_wait_thread(
         (WASMDebugInstance *)server->thread->debug_instance, tid, &status);
@@ -398,11 +456,11 @@ handle_set_current_thread(WASMGDBServer *server, char *payload)
 {
     LOG_VERBOSE("%s:%s\n", __FUNCTION__, payload, payload);
     if ('g' == *payload++) {
-        uint64_t tid;
-        tid = strtol(payload, NULL, 16);
+        uint64 tid = strtoll(payload, NULL, 16);
         if (tid > 0)
             wasm_debug_instance_set_cur_thread(
-                (WASMDebugInstance *)server->thread->debug_instance, tid);
+                (WASMDebugInstance *)server->thread->debug_instance,
+                (korp_tid)(uintptr_t)tid);
     }
     write_packet(server, "OK");
 }
@@ -410,17 +468,21 @@ handle_set_current_thread(WASMGDBServer *server, char *payload)
 void
 handle_get_register(WASMGDBServer *server, char *payload)
 {
-    int i = strtol(payload, NULL, 16);
+    uint64 regdata;
+    int32 i = strtol(payload, NULL, 16);
 
     if (i != 0) {
         write_packet(server, "E01");
         return;
     }
-    uint64_t regdata = wasm_debug_instance_get_pc(
+    regdata = wasm_debug_instance_get_pc(
         (WASMDebugInstance *)server->thread->debug_instance);
+
+    os_mutex_lock(&tmpbuf_lock);
     mem2hex((void *)&regdata, tmpbuf, 8);
     tmpbuf[8 * 2] = '\0';
     write_packet(server, tmpbuf);
+    os_mutex_unlock(&tmpbuf_lock);
 }
 
 void
@@ -443,16 +505,20 @@ handle_get_read_binary_memory(WASMGDBServer *server, char *payload)
 void
 handle_get_read_memory(WASMGDBServer *server, char *payload)
 {
-    size_t maddr, mlen;
+    uint64 maddr, mlen;
     bool ret;
 
-    sprintf(tmpbuf, "%s", "");
-    if (sscanf(payload, "%zx,%zx", &maddr, &mlen) == 2) {
+    os_mutex_lock(&tmpbuf_lock);
+    snprintf(tmpbuf, sizeof(tmpbuf), "%s", "");
+    if (sscanf(payload, "%" SCNx64 ",%" SCNx64, &maddr, &mlen) == 2) {
+        char *buff;
+
         if (mlen * 2 > MAX_PACKET_SIZE) {
             LOG_ERROR("Buffer overflow!");
             mlen = MAX_PACKET_SIZE / 2;
         }
-        char *buff = wasm_runtime_malloc(mlen);
+
+        buff = wasm_runtime_malloc(mlen);
         if (buff) {
             ret = wasm_debug_instance_get_mem(
                 (WASMDebugInstance *)server->thread->debug_instance, maddr,
@@ -464,21 +530,26 @@ handle_get_read_memory(WASMGDBServer *server, char *payload)
         }
     }
     write_packet(server, tmpbuf);
+    os_mutex_unlock(&tmpbuf_lock);
 }
 
 void
 handle_get_write_memory(WASMGDBServer *server, char *payload)
 {
-    size_t maddr, mlen, hex_len;
-    int offset, act_len;
+    size_t hex_len;
+    int32 offset, act_len;
+    uint64 maddr, mlen;
     char *buff;
     bool ret;
 
-    sprintf(tmpbuf, "%s", "");
-    if (sscanf(payload, "%zx,%zx:%n", &maddr, &mlen, &offset) == 2) {
+    os_mutex_lock(&tmpbuf_lock);
+    snprintf(tmpbuf, sizeof(tmpbuf), "%s", "");
+    if (sscanf(payload, "%" SCNx64 ",%" SCNx64 ":%n", &maddr, &mlen, &offset)
+        == 2) {
         payload += offset;
         hex_len = strlen(payload);
         act_len = hex_len / 2 < mlen ? hex_len / 2 : mlen;
+
         buff = wasm_runtime_malloc(act_len);
         if (buff) {
             hex2mem(payload, buff, act_len);
@@ -486,20 +557,22 @@ handle_get_write_memory(WASMGDBServer *server, char *payload)
                 (WASMDebugInstance *)server->thread->debug_instance, maddr,
                 buff, &mlen);
             if (ret) {
-                sprintf(tmpbuf, "%s", "OK");
+                snprintf(tmpbuf, sizeof(tmpbuf), "%s", "OK");
             }
             wasm_runtime_free(buff);
         }
     }
     write_packet(server, tmpbuf);
+    os_mutex_unlock(&tmpbuf_lock);
 }
 
 void
 handle_add_break(WASMGDBServer *server, char *payload)
 {
-    size_t type, addr, length;
+    size_t type, length;
+    uint64 addr;
 
-    if (sscanf(payload, "%zx,%zx,%zx", &type, &addr, &length) == 3) {
+    if (sscanf(payload, "%zx,%" SCNx64 ",%zx", &type, &addr, &length) == 3) {
         if (type == eBreakpointSoftware) {
             bool ret = wasm_debug_instance_add_breakpoint(
                 (WASMDebugInstance *)server->thread->debug_instance, addr,
@@ -517,9 +590,10 @@ handle_add_break(WASMGDBServer *server, char *payload)
 void
 handle_remove_break(WASMGDBServer *server, char *payload)
 {
-    size_t type, addr, length;
+    size_t type, length;
+    uint64 addr;
 
-    if (sscanf(payload, "%zx,%zx,%zx", &type, &addr, &length) == 3) {
+    if (sscanf(payload, "%zx,%" SCNx64 ",%zx", &type, &addr, &length) == 3) {
         if (type == eBreakpointSoftware) {
             bool ret = wasm_debug_instance_remove_breakpoint(
                 (WASMDebugInstance *)server->thread->debug_instance, addr,
@@ -537,8 +611,8 @@ handle_remove_break(WASMGDBServer *server, char *payload)
 void
 handle_continue_request(WASMGDBServer *server, char *payload)
 {
-    uint64_t tid;
-    uint32_t status;
+    korp_tid tid;
+    uint32 status;
 
     wasm_debug_instance_continue(
         (WASMDebugInstance *)server->thread->debug_instance);
@@ -555,8 +629,8 @@ handle_continue_request(WASMGDBServer *server, char *payload)
 void
 handle_kill_request(WASMGDBServer *server, char *payload)
 {
-    uint64_t tid;
-    uint32_t status;
+    korp_tid tid;
+    uint32 status;
 
     wasm_debug_instance_kill(
         (WASMDebugInstance *)server->thread->debug_instance);
@@ -574,11 +648,8 @@ static void
 handle_malloc(WASMGDBServer *server, char *payload)
 {
     char *args;
-    uint64_t size;
-    int map_port = MMAP_PROT_NONE;
-    uint64_t addr;
-
-    sprintf(tmpbuf, "%s", "E03");
+    uint64 addr, size;
+    int32 map_port = MMAP_PROT_NONE;
 
     args = strstr(payload, ",");
     if (args) {
@@ -589,7 +660,10 @@ handle_malloc(WASMGDBServer *server, char *payload)
         return;
     }
 
-    size = strtol(payload, NULL, 16);
+    os_mutex_lock(&tmpbuf_lock);
+    snprintf(tmpbuf, sizeof(tmpbuf), "%s", "E03");
+
+    size = strtoll(payload, NULL, 16);
     if (size > 0) {
         while (*args) {
             if (*args == 'r') {
@@ -607,27 +681,31 @@ handle_malloc(WASMGDBServer *server, char *payload)
             (WASMDebugInstance *)server->thread->debug_instance, size,
             map_port);
         if (addr) {
-            sprintf(tmpbuf, "%lx", addr);
+            snprintf(tmpbuf, sizeof(tmpbuf), "%" PRIx64, addr);
         }
     }
     write_packet(server, tmpbuf);
+    os_mutex_unlock(&tmpbuf_lock);
 }
 
 static void
 handle_free(WASMGDBServer *server, char *payload)
 {
-    uint64_t addr;
+    uint64 addr;
     bool ret;
 
-    sprintf(tmpbuf, "%s", "E03");
-    addr = strtol(payload, NULL, 16);
+    os_mutex_lock(&tmpbuf_lock);
+    snprintf(tmpbuf, sizeof(tmpbuf), "%s", "E03");
+    addr = strtoll(payload, NULL, 16);
 
     ret = wasm_debug_instance_ummap(
         (WASMDebugInstance *)server->thread->debug_instance, addr);
     if (ret) {
-        sprintf(tmpbuf, "%s", "OK");
+        snprintf(tmpbuf, sizeof(tmpbuf), "%s", "OK");
     }
+
     write_packet(server, tmpbuf);
+    os_mutex_unlock(&tmpbuf_lock);
 }
 
 void

+ 6 - 0
core/iwasm/libraries/debug-engine/handler.h

@@ -8,6 +8,12 @@
 
 #include "gdbserver.h"
 
+int
+wasm_debug_handler_init();
+
+void
+wasm_debug_handler_deinit();
+
 void
 handle_generay_set(WASMGDBServer *server, char *payload);
 

+ 20 - 23
core/iwasm/libraries/debug-engine/packets.c

@@ -3,15 +3,12 @@
  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  */
 
+#include "bh_platform.h"
 #include "packets.h"
-
-#include <stdbool.h>
-
-#include "bh_log.h"
 #include "gdbserver.h"
 
 void
-pktbuf_insert(WASMGDBServer *gdbserver, const uint8_t *buf, ssize_t len)
+pktbuf_insert(WASMGDBServer *gdbserver, const uint8 *buf, ssize_t len)
 {
     WasmDebugPacket *pkt = &gdbserver->pkt;
 
@@ -45,13 +42,13 @@ pktbuf_clear(WASMGDBServer *gdbserver)
     pkt->size = 0;
 }
 
-int
+int32
 read_data_once(WASMGDBServer *gdbserver)
 {
     ssize_t nread;
-    uint8_t buf[4096];
+    uint8 buf[4096];
 
-    nread = read(gdbserver->socket_fd, buf, sizeof(buf));
+    nread = os_socket_recv(gdbserver->socket_fd, buf, sizeof(buf));
     if (nread <= 0) {
         LOG_ERROR("Connection closed");
         return -1;
@@ -61,11 +58,11 @@ read_data_once(WASMGDBServer *gdbserver)
 }
 
 void
-write_data_raw(WASMGDBServer *gdbserver, const uint8_t *data, ssize_t len)
+write_data_raw(WASMGDBServer *gdbserver, const uint8 *data, ssize_t len)
 {
     ssize_t nwritten;
 
-    nwritten = write(gdbserver->socket_fd, data, len);
+    nwritten = os_socket_send(gdbserver->socket_fd, data, len);
     if (nwritten < 0) {
         LOG_ERROR("Write error\n");
         exit(-2);
@@ -79,21 +76,21 @@ write_hex(WASMGDBServer *gdbserver, unsigned long hex)
     size_t len;
 
     len = snprintf(buf, sizeof(buf) - 1, "%02lx", hex);
-    write_data_raw(gdbserver, (uint8_t *)buf, len);
+    write_data_raw(gdbserver, (uint8 *)buf, len);
 }
 
 void
-write_packet_bytes(WASMGDBServer *gdbserver, const uint8_t *data,
+write_packet_bytes(WASMGDBServer *gdbserver, const uint8 *data,
                    size_t num_bytes)
 {
-    uint8_t checksum;
+    uint8 checksum;
     size_t i;
 
-    write_data_raw(gdbserver, (uint8_t *)"$", 1);
+    write_data_raw(gdbserver, (uint8 *)"$", 1);
     for (i = 0, checksum = 0; i < num_bytes; ++i)
         checksum += data[i];
-    write_data_raw(gdbserver, (uint8_t *)data, num_bytes);
-    write_data_raw(gdbserver, (uint8_t *)"#", 1);
+    write_data_raw(gdbserver, (uint8 *)data, num_bytes);
+    write_data_raw(gdbserver, (uint8 *)"#", 1);
     write_hex(gdbserver, checksum);
 }
 
@@ -101,17 +98,17 @@ void
 write_packet(WASMGDBServer *gdbserver, const char *data)
 {
     LOG_VERBOSE("send replay:%s", data);
-    write_packet_bytes(gdbserver, (const uint8_t *)data, strlen(data));
+    write_packet_bytes(gdbserver, (const uint8 *)data, strlen(data));
 }
 
 void
 write_binary_packet(WASMGDBServer *gdbserver, const char *pfx,
-                    const uint8_t *data, ssize_t num_bytes)
+                    const uint8 *data, ssize_t num_bytes)
 {
-    uint8_t *buf;
+    uint8 *buf;
     ssize_t pfx_num_chars = strlen(pfx);
     ssize_t buf_num_bytes = 0, total_size;
-    int i;
+    int32 i;
 
     total_size = 2 * num_bytes + pfx_num_chars;
     buf = wasm_runtime_malloc(total_size);
@@ -125,7 +122,7 @@ write_binary_packet(WASMGDBServer *gdbserver, const char *pfx,
     buf_num_bytes += pfx_num_chars;
 
     for (i = 0; i < num_bytes; ++i) {
-        uint8_t b = data[i];
+        uint8 b = data[i];
         switch (b) {
             case '#':
             case '$':
@@ -148,7 +145,7 @@ skip_to_packet_start(WASMGDBServer *gdbserver)
 {
     ssize_t start_index = -1, i;
 
-    for (i = 0; i < gdbserver->pkt.size; ++i) {
+    for (i = 0; i < (ssize_t)gdbserver->pkt.size; ++i) {
         if (gdbserver->pkt.buf[i] == '$') {
             start_index = i;
             break;
@@ -176,6 +173,6 @@ read_packet(WASMGDBServer *gdbserver)
             return false;
     }
     if (!gdbserver->noack)
-        write_data_raw(gdbserver, (uint8_t *)"+", 1);
+        write_data_raw(gdbserver, (uint8 *)"+", 1);
     return true;
 }

+ 0 - 2
core/iwasm/libraries/debug-engine/packets.h

@@ -6,8 +6,6 @@
 #ifndef PACKETS_H
 #define PACKETS_H
 
-#include <stdint.h>
-#include <unistd.h>
 #include "gdbserver.h"
 
 bool

+ 7 - 5
core/iwasm/libraries/debug-engine/utils.c

@@ -5,7 +5,9 @@
 
 #include "utils.h"
 
-int
+static const char hexchars[] = "0123456789abcdef";
+
+int32
 hex(char ch)
 {
     if ((ch >= 'a') && (ch <= 'f'))
@@ -18,9 +20,9 @@ hex(char ch)
 }
 
 char *
-mem2hex(char *mem, char *buf, int count)
+mem2hex(char *mem, char *buf, int32 count)
 {
-    unsigned char ch;
+    uint8 ch;
 
     for (int i = 0; i < count; i++) {
         ch = *(mem++);
@@ -32,9 +34,9 @@ mem2hex(char *mem, char *buf, int count)
 }
 
 char *
-hex2mem(char *buf, char *mem, int count)
+hex2mem(char *buf, char *mem, int32 count)
 {
-    unsigned char ch;
+    uint8 ch;
 
     for (int i = 0; i < count; i++) {
         ch = hex(*buf++) << 4;

+ 6 - 6
core/iwasm/libraries/debug-engine/utils.h

@@ -6,18 +6,18 @@
 #ifndef UTILS_H
 #define UTILS_H
 
-static const char hexchars[] = "0123456789abcdef";
+#include "bh_platform.h"
 
-int
+int32
 hex(char ch);
 
 char *
-mem2hex(char *mem, char *buf, int count);
+mem2hex(char *mem, char *buf, int32 count);
 
 char *
-hex2mem(char *buf, char *mem, int count);
+hex2mem(char *buf, char *mem, int32 count);
 
-int
-unescape(char *msg, int len);
+int32
+unescape(char *msg, int32 len);
 
 #endif /* UTILS_H */

+ 2 - 0
core/shared/platform/android/platform_internal.h

@@ -58,6 +58,8 @@ typedef pthread_t korp_thread;
 
 #define os_thread_local_attribute __thread
 
+#define bh_socket_t int
+
 #if WASM_DISABLE_HW_BOUND_CHECK == 0
 #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)            \
     || defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \

+ 124 - 0
core/shared/platform/common/posix/posix_socket.c

@@ -0,0 +1,124 @@
+/*
+ * Copyright (C) 2021 Intel Corporation.  All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include "platform_api_vmcore.h"
+#include "platform_api_extension.h"
+
+#include <arpa/inet.h>
+
+int
+os_socket_create(bh_socket_t *sock, int tcp_or_udp)
+{
+    if (!sock) {
+        return BHT_ERROR;
+    }
+
+    if (1 == tcp_or_udp) {
+        *sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+    }
+    else if (0 == tcp_or_udp) {
+        *sock = socket(AF_INET, SOCK_DGRAM, 0);
+    }
+
+    return (*sock == -1) ? BHT_ERROR : BHT_OK;
+}
+
+int
+os_socket_bind(bh_socket_t socket, const char *host, int *port)
+{
+    struct sockaddr_in addr;
+    struct linger ling;
+    socklen_t socklen;
+    int ret;
+
+    assert(host);
+    assert(port);
+
+    ling.l_onoff = 1;
+    ling.l_linger = 0;
+
+    ret = fcntl(socket, F_SETFD, FD_CLOEXEC);
+    if (ret < 0) {
+        goto fail;
+    }
+
+    ret = setsockopt(socket, SOL_SOCKET, SO_LINGER, &ling, sizeof(ling));
+    if (ret < 0) {
+        goto fail;
+    }
+
+    addr.sin_addr.s_addr = inet_addr(host);
+    addr.sin_port = htons(*port);
+    addr.sin_family = AF_INET;
+
+    ret = bind(socket, (struct sockaddr *)&addr, sizeof(addr));
+    if (ret < 0) {
+        goto fail;
+    }
+
+    socklen = sizeof(addr);
+    if (getsockname(socket, (void *)&addr, &socklen) == -1) {
+        goto fail;
+    }
+
+    *port = ntohs(addr.sin_port);
+
+    return BHT_OK;
+
+fail:
+    return BHT_ERROR;
+}
+
+int
+os_socket_listen(bh_socket_t socket, int max_client)
+{
+    if (listen(socket, max_client) != 0) {
+        return BHT_ERROR;
+    }
+
+    return BHT_OK;
+}
+
+int
+os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr,
+                 unsigned int *addrlen)
+{
+    struct sockaddr addr_tmp;
+    unsigned int len = sizeof(struct sockaddr);
+
+    *sock = accept(server_sock, (struct sockaddr *)&addr_tmp, &len);
+
+    if (*sock < 0) {
+        return BHT_ERROR;
+    }
+
+    return BHT_OK;
+}
+
+int
+os_socket_recv(bh_socket_t socket, void *buf, unsigned int len)
+{
+    return recv(socket, buf, len, 0);
+}
+
+int
+os_socket_send(bh_socket_t socket, const void *buf, unsigned int len)
+{
+    return send(socket, buf, len, 0);
+}
+
+int
+os_socket_close(bh_socket_t socket)
+{
+    close(socket);
+    return BHT_OK;
+}
+
+int
+os_socket_shutdown(bh_socket_t socket)
+{
+    shutdown(socket, O_RDWR);
+    return BHT_OK;
+}

+ 2 - 0
core/shared/platform/darwin/platform_internal.h

@@ -59,6 +59,8 @@ typedef pthread_t korp_thread;
 
 #define os_thread_local_attribute __thread
 
+#define bh_socket_t int
+
 #if WASM_DISABLE_HW_BOUND_CHECK == 0
 #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)            \
     || defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \

+ 115 - 0
core/shared/platform/include/platform_api_extension.h

@@ -23,6 +23,11 @@ extern "C" {
  *                                                 *
  ***************************************************/
 
+/****************************************************
+ *                     Section 1                    *
+ *                Multi thread support              *
+ ****************************************************/
+
 /**
  * NOTES:
  * 1. If you are building VM core only, it must be implemented to
@@ -174,6 +179,116 @@ os_cond_reltimedwait(korp_cond *cond, korp_mutex *mutex, uint64 useconds);
 int
 os_cond_signal(korp_cond *cond);
 
+/****************************************************
+ *                     Section 2                    *
+ *                   Socket support                 *
+ ****************************************************/
+
+/**
+ * NOTES:
+ * Socket APIs are required by source debugging feature.
+ * If you don't need source debugging feature, then no
+ * need to implement these APIs
+ */
+
+/**
+ * Create a socket
+ *
+ * @param sock [OUTPUT] the pointer of socket
+ * @param tcp_or_udp 1 for tcp, 0 for udp
+ *
+ * @return 0 if success, -1 otherwise
+ */
+int
+os_socket_create(bh_socket_t *sock, int tcp_or_udp);
+
+/**
+ * Assign the address and port to the socket
+ *
+ * @param socket the socket to bind
+ * @param addr the ip address, only IPv4 supported currently
+ * @param port [INPUT/OUTPUT] the port number, if the value is 0,
+ *             it will use a port assigned by OS. On return it will
+ *             contain the actual bound port number
+ *
+ * @return 0 if success, -1 otherwise
+ */
+int
+os_socket_bind(bh_socket_t socket, const char *addr, int *port);
+
+/**
+ * Make the socket as a passive socket to accept incoming connection requests
+ *
+ * @param socket the socket to listen
+ * @param max_client maximum clients
+ *
+ * @return 0 if success, -1 otherwise
+ */
+int
+os_socket_listen(bh_socket_t socket, int max_client);
+
+/**
+ * Accept an incoming connection
+ *
+ * @param server_sock the socket to accept new connections
+ * @param sock [OUTPUT] the connected socket
+ * @param addr [OUTPUT] the address of the peer socket. If addr is NULL,
+ *             nothing is filled in, and addrlen will not be used
+ * @param addrlen [INPUT/OUTPUT] the size (in bytes) of the structure
+ *                pointed to by addr, on return it will contain the actual
+ *                size of the peer address
+ *
+ * @return 0 if success, -1 otherwise
+ */
+int
+os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr,
+                 unsigned int *addrlen);
+
+/**
+ * Blocking receive message from a socket.
+ *
+ * @param socket the socket to receive message from
+ * @param buf the buffer to store the data
+ * @param len length of the buffer, this API does not guarantee that
+ *            [len] bytes are received
+ *
+ * @return number of bytes received if success, -1 otherwise
+ */
+int
+os_socket_recv(bh_socket_t socket, void *buf, unsigned int len);
+
+/**
+ * Blocking send message on a socket
+ *
+ * @param socket the socket to send message
+ * @param buf the buffer of data to be sent
+ * @param len length of the buffer
+ *
+ * @return number of bytes sent if success, -1 otherwise
+ */
+int
+os_socket_send(bh_socket_t socket, const void *buf, unsigned int len);
+
+/**
+ * Close a socket
+ *
+ * @param socket the socket to be closed
+ *
+ * @return always return 0
+ */
+int
+os_socket_close(bh_socket_t socket);
+
+/**
+ * Shutdown a socket
+ *
+ * @param socket the socket to be shutdown
+ *
+ * @return always return 0
+ */
+int
+os_socket_shutdown(bh_socket_t socket);
+
 #ifdef __cplusplus
 }
 #endif

+ 49 - 10
core/shared/platform/include/platform_common.h

@@ -104,6 +104,25 @@ typedef int64_t int64;
 
 typedef void *(*thread_start_routine_t)(void *);
 
+#ifndef bh_socket_t
+/* If no socket defined on current platform,
+    give a fake definition to make the compiler happy */
+#define bh_socket_t int
+#endif
+
+/* Format specifiers macros in case
+    they are not provided by compiler */
+#ifndef __PRI64_PREFIX
+#if UINTPTR_MAX == UINT64_MAX
+#define __PRI64_PREFIX "l"
+#define __PRIPTR_PREFIX "l"
+#else
+#define __PRI64_PREFIX "ll"
+#define __PRIPTR_PREFIX
+#endif
+#endif /* #ifndef __PRI64_PREFIX */
+
+/* Macros for printing format specifiers */
 #ifndef PRId32
 #define PRId32 "d"
 #endif
@@ -120,16 +139,6 @@ typedef void *(*thread_start_routine_t)(void *);
 #define PRIX32 "X"
 #endif
 
-#ifndef __PRI64_PREFIX
-#if UINTPTR_MAX == UINT64_MAX
-#define __PRI64_PREFIX "l"
-#define __PRIPTR_PREFIX "l"
-#else
-#define __PRI64_PREFIX "ll"
-#define __PRIPTR_PREFIX
-#endif
-#endif
-
 #ifndef PRId64
 #define PRId64 __PRI64_PREFIX "d"
 #endif
@@ -142,10 +151,40 @@ typedef void *(*thread_start_routine_t)(void *);
 #ifndef PRIX64
 #define PRIX64 __PRI64_PREFIX "X"
 #endif
+#ifndef PRIxPTR
+#define PRIxPTR __PRIPTR_PREFIX "x"
+#endif
 #ifndef PRIXPTR
 #define PRIXPTR __PRIPTR_PREFIX "X"
 #endif
 
+/* Macros for scanning format specifiers */
+#ifndef SCNd32
+#define SCNd32 "d"
+#endif
+#ifndef SCNi32
+#define SCNi32 "i"
+#endif
+#ifndef SCNu32
+#define SCNu32 "u"
+#endif
+#ifndef SCNx32
+#define SCNx32 "x"
+#endif
+
+#ifndef SCNd64
+#define SCNd64 __PRI64_PREFIX "d"
+#endif
+#ifndef SCNu64
+#define SCNu64 __PRI64_PREFIX "u"
+#endif
+#ifndef SCNx64
+#define SCNx64 __PRI64_PREFIX "x"
+#endif
+#ifndef SCNxPTR
+#define SCNxPTR __PRIPTR_PREFIX "x"
+#endif
+
 #ifdef __cplusplus
 }
 #endif

+ 2 - 0
core/shared/platform/linux/platform_internal.h

@@ -58,6 +58,8 @@ typedef pthread_t korp_thread;
 
 #define os_thread_local_attribute __thread
 
+#define bh_socket_t int
+
 #if WASM_DISABLE_HW_BOUND_CHECK == 0
 #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)            \
     || defined(BUILD_TARGET_AARCH64) || defined(BUILD_TARGET_RISCV64_LP64D) \

+ 12 - 0
core/shared/platform/windows/platform_init.c

@@ -11,15 +11,27 @@ os_thread_sys_init();
 void
 os_thread_sys_destroy();
 
+int
+init_winsock();
+
+void
+deinit_winsock();
+
 int
 bh_platform_init()
 {
+    if (init_winsock() != 0) {
+        return -1;
+    }
+
     return os_thread_sys_init();
 }
 
 void
 bh_platform_destroy()
 {
+    deinit_winsock();
+
     os_thread_sys_destroy();
 }
 

+ 12 - 0
core/shared/platform/windows/platform_internal.h

@@ -26,6 +26,8 @@
 #include <malloc.h>
 #include <process.h>
 #include <Windows.h>
+#include <BaseTsd.h>
+#include <winsock2.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -35,12 +37,20 @@ extern "C" {
 #define BH_PLATFORM_WINDOWS
 #endif
 
+#ifdef _MSC_VER
+#ifndef PATH_MAX
+#define PATH_MAX MAX_PATH
+#endif
+#endif /* #ifdef _MSC_VER */
+
 /* Stack size of applet threads's native part.  */
 #define BH_APPLET_PRESERVED_STACK_SIZE (32 * 1024)
 
 /* Default thread priority */
 #define BH_THREAD_DEFAULT_PRIORITY 0
 
+typedef SSIZE_T ssize_t;
+
 typedef void *korp_thread;
 typedef void *korp_tid;
 typedef void *korp_mutex;
@@ -53,6 +63,8 @@ typedef struct korp_cond {
     os_thread_wait_list thread_wait_list;
 } korp_cond;
 
+#define bh_socket_t SOCKET
+
 unsigned
 os_getpagesize();
 void *

+ 140 - 0
core/shared/platform/windows/win_socket.c

@@ -0,0 +1,140 @@
+/*
+ * Copyright (C) 2021 Intel Corporation.  All rights reserved.
+ * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+ */
+
+#include "platform_api_vmcore.h"
+#include "platform_api_extension.h"
+
+/* link with Ws2_32.lib */
+#pragma comment(lib, "ws2_32.lib")
+
+static bool is_winsock_inited = false;
+
+int
+init_winsock()
+{
+    WSADATA wsaData;
+
+    if (!is_winsock_inited) {
+        if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) {
+            os_printf("winsock init failed");
+            return BHT_ERROR;
+        }
+
+        is_winsock_inited = true;
+    }
+
+    return BHT_OK;
+}
+
+void
+deinit_winsock()
+{
+    if (is_winsock_inited) {
+        WSACleanup();
+    }
+}
+
+int
+os_socket_create(bh_socket_t *sock, int tcp_or_udp)
+{
+    if (!sock) {
+        return BHT_ERROR;
+    }
+
+    if (1 == tcp_or_udp) {
+        *sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
+    }
+    else if (0 == tcp_or_udp) {
+        *sock = socket(AF_INET, SOCK_DGRAM, 0);
+    }
+
+    return (*sock == -1) ? BHT_ERROR : BHT_OK;
+}
+
+int
+os_socket_bind(bh_socket_t socket, const char *host, int *port)
+{
+    struct sockaddr_in addr;
+    int socklen, ret;
+
+    assert(host);
+    assert(port);
+
+    addr.sin_addr.s_addr = inet_addr(host);
+    addr.sin_port = htons(*port);
+    addr.sin_family = AF_INET;
+
+    ret = bind(socket, (struct sockaddr *)&addr, sizeof(addr));
+    if (ret < 0) {
+        goto fail;
+    }
+
+    socklen = sizeof(addr);
+    if (getsockname(socket, (void *)&addr, &socklen) == -1) {
+        os_printf("getsockname failed with error %d\n", WSAGetLastError());
+        goto fail;
+    }
+
+    *port = ntohs(addr.sin_port);
+
+    return BHT_OK;
+
+fail:
+    return BHT_ERROR;
+}
+
+int
+os_socket_listen(bh_socket_t socket, int max_client)
+{
+    if (listen(socket, max_client) != 0) {
+        os_printf("socket listen failed with error %d\n", WSAGetLastError());
+        return BHT_ERROR;
+    }
+
+    return BHT_OK;
+}
+
+int
+os_socket_accept(bh_socket_t server_sock, bh_socket_t *sock, void *addr,
+                 unsigned int *addrlen)
+{
+    struct sockaddr addr_tmp;
+    unsigned int len = sizeof(struct sockaddr);
+
+    *sock = accept(server_sock, (struct sockaddr *)&addr_tmp, &len);
+
+    if (*sock < 0) {
+        os_printf("socket accept failed with error %d\n", WSAGetLastError());
+        return BHT_ERROR;
+    }
+
+    return BHT_OK;
+}
+
+int
+os_socket_recv(bh_socket_t socket, void *buf, unsigned int len)
+{
+    return recv(socket, buf, len, 0);
+}
+
+int
+os_socket_send(bh_socket_t socket, const void *buf, unsigned int len)
+{
+    return send(socket, buf, len, 0);
+}
+
+int
+os_socket_close(bh_socket_t socket)
+{
+    closesocket(socket);
+    return BHT_OK;
+}
+
+int
+os_socket_shutdown(bh_socket_t socket)
+{
+    shutdown(socket, SD_BOTH);
+    return BHT_OK;
+}

+ 1 - 0
product-mini/platforms/windows/CMakeLists.txt

@@ -92,6 +92,7 @@ set (WAMR_ROOT_DIR ${CMAKE_CURRENT_SOURCE_DIR}/../../..)
 include (${WAMR_ROOT_DIR}/build-scripts/runtime_lib.cmake)
 add_library(vmlib ${WAMR_RUNTIME_LIB_SOURCE})
 
+set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DWIN32_LEAN_AND_MEAN")
 set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /SAFESEH:NO")
 set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} /SAFESEH:NO")
 

+ 29 - 0
product-mini/platforms/windows/main.c

@@ -45,6 +45,10 @@ print_help()
 #endif
 #if WASM_ENABLE_LIB_PTHREAD != 0
     printf("  --max-threads=n        Set maximum thread number per cluster, default is 4\n");
+#endif
+#if WASM_ENABLE_DEBUG_INTERP != 0
+    printf("  -g=ip:port             Set the debug sever address, default is debug disabled\n");
+    printf("                           if port is 0, then a random port will be used\n");
 #endif
     return 1;
 }
@@ -236,6 +240,11 @@ main(int argc, char *argv[])
     const char *env_list[8] = { NULL };
     uint32 env_list_size = 0;
 #endif
+#if WASM_ENABLE_DEBUG_INTERP != 0
+    char *ip_addr = NULL;
+    /* int platform_port = 0; */
+    int instance_port = 0;
+#endif
 
     /* Process options. */
     for (argc--, argv++; argc > 0 && argv[0][0] == '-'; argc--, argv++) {
@@ -313,6 +322,19 @@ main(int argc, char *argv[])
                 return print_help();
             wasm_runtime_set_max_thread_num(atoi(argv[0] + 14));
         }
+#endif
+#if WASM_ENABLE_DEBUG_INTERP != 0
+        else if (!strncmp(argv[0], "-g=", 3)) {
+            char *port_str = strchr(argv[0] + 3, ':');
+            char *port_end;
+            if (port_str == NULL)
+                return print_help();
+            *port_str = '\0';
+            instance_port = strtoul(port_str + 1, &port_end, 10);
+            if (port_str[1] == '\0' || *port_end != '\0')
+                return print_help();
+            ip_addr = argv[0] + 3;
+        }
 #endif
         else
             return print_help();
@@ -338,6 +360,13 @@ main(int argc, char *argv[])
     init_args.mem_alloc_option.allocator.free_func = free;
 #endif
 
+#if WASM_ENABLE_DEBUG_INTERP != 0
+    init_args.platform_port = 0;
+    init_args.instance_port = instance_port;
+    if (ip_addr)
+        strcpy(init_args.ip_addr, ip_addr);
+#endif
+
     /* initialize runtime environment */
     if (!wasm_runtime_full_init(&init_args)) {
         printf("Init runtime environment failed.\n");