Ver Fonte

windows: fix vectored exception handler lifecycle for repeated thread env init/destroy (#4842)

* Fix Windows VEH registration/removal lifecycle
* Remove redundant OS_THREAD_MUTEX_INITIALIZER guards

Since the code is already inside #ifdef BH_PLATFORM_WINDOWS,
the macro is always defined. Use NULL directly for clarity.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
kogum4 há 7 horas atrás
pai
commit
dcf137e961
1 ficheiros alterados com 41 adições e 3 exclusões
  1. 41 3
      core/iwasm/common/wasm_runtime_common.c

+ 41 - 3
core/iwasm/common/wasm_runtime_common.c

@@ -415,19 +415,39 @@ runtime_exception_handler(EXCEPTION_POINTERS *exce_info)
 }
 }
 #endif /* end of BH_PLATFORM_WINDOWS */
 #endif /* end of BH_PLATFORM_WINDOWS */
 
 
+#ifdef BH_PLATFORM_WINDOWS
+static PVOID runtime_exception_handler_handle = NULL;
+static int32 runtime_exception_handler_ref_count = 0;
+static korp_mutex runtime_exception_handler_lock = NULL;
+#endif
+
 static bool
 static bool
 runtime_signal_init()
 runtime_signal_init()
 {
 {
 #ifndef BH_PLATFORM_WINDOWS
 #ifndef BH_PLATFORM_WINDOWS
     return os_thread_signal_init(runtime_signal_handler) == 0 ? true : false;
     return os_thread_signal_init(runtime_signal_handler) == 0 ? true : false;
 #else
 #else
-    if (os_thread_signal_init() != 0)
+    os_mutex_lock(&runtime_exception_handler_lock);
+
+    if (os_thread_signal_init() != 0) {
+        os_mutex_unlock(&runtime_exception_handler_lock);
         return false;
         return false;
+    }
 
 
-    if (!AddVectoredExceptionHandler(1, runtime_exception_handler)) {
+    if (runtime_exception_handler_ref_count == 0) {
+        runtime_exception_handler_handle =
+            AddVectoredExceptionHandler(1, runtime_exception_handler);
+    }
+
+    if (!runtime_exception_handler_handle) {
         os_thread_signal_destroy();
         os_thread_signal_destroy();
+        os_mutex_unlock(&runtime_exception_handler_lock);
         return false;
         return false;
     }
     }
+
+    runtime_exception_handler_ref_count++;
+
+    os_mutex_unlock(&runtime_exception_handler_lock);
 #endif
 #endif
     return true;
     return true;
 }
 }
@@ -436,7 +456,25 @@ static void
 runtime_signal_destroy()
 runtime_signal_destroy()
 {
 {
 #ifdef BH_PLATFORM_WINDOWS
 #ifdef BH_PLATFORM_WINDOWS
-    RemoveVectoredExceptionHandler(runtime_exception_handler);
+    os_mutex_lock(&runtime_exception_handler_lock);
+
+    if (runtime_exception_handler_ref_count > 0) {
+        runtime_exception_handler_ref_count--;
+    }
+
+    if (runtime_exception_handler_ref_count == 0
+        && runtime_exception_handler_handle) {
+        if (RemoveVectoredExceptionHandler(runtime_exception_handler_handle)) {
+            runtime_exception_handler_handle = NULL;
+        }
+        else {
+            /* Keep the handle so future init/destroy cycles can retry remove.
+             * Clearing it here may leave a live callback registered forever. */
+            runtime_exception_handler_ref_count = 1;
+        }
+    }
+
+    os_mutex_unlock(&runtime_exception_handler_lock);
 #endif
 #endif
     os_thread_signal_destroy();
     os_thread_signal_destroy();
 }
 }