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

Fix dead lock in source debugger (#2040)

Xu Jun 2 лет назад
Родитель
Сommit
d75cb3224f

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

@@ -1079,12 +1079,14 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
         /* Record the current frame_ip, so when exception occurs,         \
            debugger can know the exact opcode who caused the exception */ \
         frame_ip_orig = frame_ip;                                         \
+        os_mutex_lock(&exec_env->wait_lock);                              \
         while (exec_env->current_status->signal_flag == WAMR_SIG_SINGSTEP \
                && exec_env->current_status->step_count++ == 1) {          \
             exec_env->current_status->step_count = 0;                     \
             SYNC_ALL_TO_FRAME();                                          \
             wasm_cluster_thread_waiting_run(exec_env);                    \
         }                                                                 \
+        os_mutex_unlock(&exec_env->wait_lock);                            \
         goto *handle_table[*frame_ip++];                                  \
     } while (0)
 #else
@@ -1095,12 +1097,14 @@ wasm_interp_call_func_import(WASMModuleInstance *module_inst,
 #define HANDLE_OP(opcode) case opcode:
 #if WASM_ENABLE_THREAD_MGR != 0 && WASM_ENABLE_DEBUG_INTERP != 0
 #define HANDLE_OP_END()                                            \
+    os_mutex_lock(&exec_env->wait_lock);                           \
     if (exec_env->current_status->signal_flag == WAMR_SIG_SINGSTEP \
         && exec_env->current_status->step_count++ == 2) {          \
         exec_env->current_status->step_count = 0;                  \
         SYNC_ALL_TO_FRAME();                                       \
         wasm_cluster_thread_waiting_run(exec_env);                 \
     }                                                              \
+    os_mutex_unlock(&exec_env->wait_lock);                         \
     continue
 #else
 #define HANDLE_OP_END() continue

+ 0 - 6
core/iwasm/libraries/thread-mgr/thread_manager.c

@@ -793,18 +793,12 @@ notify_debug_instance_exit(WASMExecEnv *exec_env)
 void
 wasm_cluster_thread_waiting_run(WASMExecEnv *exec_env)
 {
-    os_mutex_lock(&exec_env->wait_lock);
-
-    /* Wake up debugger thread after we get the lock, otherwise we may miss the
-     * signal from debugger thread, see
-     * https://github.com/bytecodealliance/wasm-micro-runtime/issues/1860 */
     exec_env->current_status->running_status = STATUS_STOP;
     notify_debug_instance(exec_env);
 
     while (!wasm_cluster_thread_is_running(exec_env)) {
         os_cond_wait(&exec_env->wait_cond, &exec_env->wait_lock);
     }
-    os_mutex_unlock(&exec_env->wait_lock);
 }
 
 void

+ 3 - 0
core/iwasm/libraries/thread-mgr/thread_manager.h

@@ -180,6 +180,9 @@ wasm_cluster_destroy_exenv_status(WASMCurrentEnvStatus *status);
 void
 wasm_cluster_send_signal_all(WASMCluster *cluster, uint32 signo);
 
+/* This function must be called with exec_env->wait_lock locked, otherwise we
+ * may miss the signal from debugger thread, see
+ * https://github.com/bytecodealliance/wasm-micro-runtime/issues/1860 */
 void
 wasm_cluster_thread_waiting_run(WASMExecEnv *exec_env);