Просмотр исходного кода

Support print exception info in source debugger (#1212)

Xu Jun 3 лет назад
Родитель
Сommit
93607d0fac

+ 17 - 0
core/iwasm/interpreter/wasm_interp_classic.c

@@ -14,6 +14,7 @@
 #endif
 #if WASM_ENABLE_THREAD_MGR != 0 && WASM_ENABLE_DEBUG_INTERP != 0
 #include "../libraries/thread-mgr/thread_manager.h"
+#include "../libraries/debug-engine/debug_engine.h"
 #endif
 
 typedef int32 CellType_I32;
@@ -930,6 +931,9 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
 #if WASM_ENABLE_THREAD_MGR != 0 && WASM_ENABLE_DEBUG_INTERP != 0
 #define HANDLE_OP_END()                                                   \
     do {                                                                  \
+        /* Record the current frame_ip, so when exception occurs,         \
+           debugger can know the exact opcode who caused the exception */ \
+        frame_ip_orig = frame_ip;                                         \
         while (exec_env->current_status->signal_flag == WAMR_SIG_SINGSTEP \
                && exec_env->current_status->step_count++ == 1) {          \
             exec_env->current_status->step_count = 0;                     \
@@ -1007,6 +1011,10 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
     uint32 cache_index, type_index, param_cell_num, cell_num;
     uint8 value_type;
 
+#if WASM_ENABLE_DEBUG_INTERP != 0
+    uint8 *frame_ip_orig = NULL;
+#endif
+
 #if WASM_ENABLE_LABELS_AS_VALUES != 0
 #define HANDLE_OPCODE(op) &&HANDLE_##op
     DEFINE_GOTO_TABLE(const void *, handle_table);
@@ -3734,6 +3742,15 @@ wasm_interp_call_func_bytecode(WASMModuleInstance *module,
         wasm_set_exception(module, "out of bounds memory access");
 
     got_exception:
+#if WASM_ENABLE_DEBUG_INTERP != 0
+        if (wasm_exec_env_get_instance(exec_env) != NULL) {
+            uint8 *frame_ip_temp = frame_ip;
+            frame_ip = frame_ip_orig;
+            wasm_cluster_thread_send_signal(exec_env, WAMR_SIG_TRAP);
+            CHECK_SUSPEND_FLAGS();
+            frame_ip = frame_ip_temp;
+        }
+#endif
         SYNC_ALL_TO_FRAME();
         return;
 

+ 5 - 2
core/iwasm/libraries/debug-engine/debug_engine.c

@@ -456,7 +456,7 @@ wasm_debug_instance_destroy(WASMCluster *cluster)
     }
 }
 
-static WASMExecEnv *
+WASMExecEnv *
 wasm_debug_instance_get_current_env(WASMDebugInstance *instance)
 {
     WASMExecEnv *exec_env = NULL;
@@ -829,7 +829,10 @@ WASMDebugInstance *
 wasm_exec_env_get_instance(WASMExecEnv *exec_env)
 {
     WASMDebugInstance *instance = NULL;
-    bh_assert(g_debug_engine);
+
+    if (!g_debug_engine) {
+        return NULL;
+    }
 
     os_mutex_lock(&g_debug_engine->instance_list_lock);
     instance = bh_list_first_elem(&g_debug_engine->debug_instance_list);

+ 3 - 0
core/iwasm/libraries/debug-engine/debug_engine.h

@@ -128,6 +128,9 @@ wasm_debug_set_engine_active(bool active);
 bool
 wasm_debug_get_engine_active(void);
 
+WASMExecEnv *
+wasm_debug_instance_get_current_env(WASMDebugInstance *instance);
+
 uint64
 wasm_debug_instance_get_pid(WASMDebugInstance *instance);
 

+ 36 - 13
core/iwasm/libraries/debug-engine/handler.c

@@ -334,6 +334,8 @@ send_thread_stop_status(WASMGDBServer *server, uint32 status, korp_tid tid)
     char pc_string[17];
     uint32 tids_count, i = 0;
     uint32 gdb_status = status;
+    WASMExecEnv *exec_env;
+    const char *exception;
 
     if (status == 0) {
         os_mutex_lock(&tmpbuf_lock);
@@ -370,20 +372,41 @@ send_thread_stop_status(WASMGDBServer *server, uint32 status, korp_tid tid)
     mem2hex((void *)&pc, pc_string, 8);
     pc_string[8 * 2] = '\0';
 
-    if (status == WAMR_SIG_TRAP) {
-        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 += snprintf(tmpbuf + len, sizeof(tmpbuf) - len,
-                        "thread-pcs:%" PRIx64 ";00:%s,reason:%s;", pc,
-                        pc_string, "trace");
+    exec_env = wasm_debug_instance_get_current_env(
+        (WASMDebugInstance *)server->thread->debug_instance);
+    exception =
+        wasm_runtime_get_exception(wasm_runtime_get_module_inst(exec_env));
+    if (exception) {
+        /* When exception occurs, use reason:exception so the description can be
+         * correctly processed by LLDB */
+        uint32 exception_len = strlen(exception);
+        len +=
+            snprintf(tmpbuf + len, sizeof(tmpbuf) - len,
+                     "thread-pcs:%" PRIx64 ";00:%s;reason:%s;description:", pc,
+                     pc_string, "exception");
+        /* The description should be encoded as HEX */
+        for (i = 0; i < exception_len; i++) {
+            len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len, "%02x",
+                            exception[i]);
+        }
+        len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len, ";");
     }
-    else if (status > 0) {
-        len += snprintf(tmpbuf + len, sizeof(tmpbuf) - len,
-                        "thread-pcs:%" PRIx64 ";00:%s,reason:%s;", pc,
-                        pc_string, "signal");
+    else {
+        if (status == WAMR_SIG_TRAP) {
+            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 += snprintf(tmpbuf + len, sizeof(tmpbuf) - len,
+                            "thread-pcs:%" PRIx64 ";00:%s;reason:%s;", pc,
+                            pc_string, "trace");
+        }
+        else if (status > 0) {
+            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);