Browse Source

chore: cherry-pick c03569f from libuv (#40101)

Refs https://github.com/libuv/libuv/commit/c03569f0df3bb26e7e7bec9feabd9ae3c372568e
Robo 1 year ago
parent
commit
fdf8b02e14

+ 1 - 0
patches/node/.patches

@@ -52,3 +52,4 @@ lib_fix_broadcastchannel_initialization_location.patch
 src_adapt_to_v8_exception_api_change.patch
 lib_test_do_not_hardcode_buffer_kmaxlength.patch
 fix_handle_possible_disabled_sharedarraybuffer.patch
+win_process_avoid_assert_after_spawning_store_app_4152.patch

+ 85 - 0
patches/node/win_process_avoid_assert_after_spawning_store_app_4152.patch

@@ -0,0 +1,85 @@
+From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
+From: Jameson Nash <[email protected]>
+Date: Mon, 2 Oct 2023 15:15:18 +0200
+Subject: win,process: avoid assert after spawning Store app (#4152)
+
+Make sure this handle is functional. The Windows kernel seems to have a
+bug that if the first use of AssignProcessToJobObject is for a Windows
+Store program, subsequent attempts to use the handle with fail with
+INVALID_PARAMETER (87). This is possilby because all uses of the handle
+must be for the same Terminal Services session. We can ensure it is
+tied to our current session now by adding ourself to it. We could
+remove ourself afterwards, but there doesn't seem to be a reason to.
+
+Secondly, we start the process suspended so that we can make sure we
+added it to the job control object before it does anything itself (such
+as launch more jobs or exit).
+
+Fixes: https://github.com/JuliaLang/julia/issues/51461
+
+diff --git a/deps/uv/src/win/process.c b/deps/uv/src/win/process.c
+index 3e451e2291d6ed200ec258e874becbbea22bbc27..a71a08bdd60166ef1d4ef490ff3e083b44188852 100644
+--- a/deps/uv/src/win/process.c
++++ b/deps/uv/src/win/process.c
+@@ -105,6 +105,21 @@ static void uv__init_global_job_handle(void) {
+                                &info,
+                                sizeof info))
+     uv_fatal_error(GetLastError(), "SetInformationJobObject");
++
++
++  if (!AssignProcessToJobObject(uv_global_job_handle_, GetCurrentProcess())) {
++    /* Make sure this handle is functional. The Windows kernel has a bug that
++     * if the first use of AssignProcessToJobObject is for a Windows Store
++     * program, subsequent attempts to use the handle with fail with
++     * INVALID_PARAMETER (87). This is possibly because all uses of the handle
++     * must be for the same Terminal Services session. We can ensure it is tied
++     * to our current session now by adding ourself to it. We could remove
++     * ourself afterwards, but there doesn't seem to be a reason to.
++     */
++    DWORD err = GetLastError();
++    if (err != ERROR_ACCESS_DENIED)
++      uv_fatal_error(err, "AssignProcessToJobObject");
++  }
+ }
+ 
+ 
+@@ -1102,6 +1117,7 @@ int uv_spawn(uv_loop_t* loop,
+      * breakaway.
+      */
+     process_flags |= DETACHED_PROCESS | CREATE_NEW_PROCESS_GROUP;
++    process_flags |= CREATE_SUSPENDED;
+   }
+ 
+   if (!CreateProcessW(application_path,
+@@ -1119,11 +1135,6 @@ int uv_spawn(uv_loop_t* loop,
+     goto done;
+   }
+ 
+-  /* Spawn succeeded. Beyond this point, failure is reported asynchronously. */
+-
+-  process->process_handle = info.hProcess;
+-  process->pid = info.dwProcessId;
+-
+   /* If the process isn't spawned as detached, assign to the global job object
+    * so windows will kill it when the parent process dies. */
+   if (!(options->flags & UV_PROCESS_DETACHED)) {
+@@ -1146,6 +1157,19 @@ int uv_spawn(uv_loop_t* loop,
+     }
+   }
+ 
++  if (process_flags & CREATE_SUSPENDED) {
++    if (ResumeThread(info.hThread) == ((DWORD)-1)) {
++      err = GetLastError();
++      TerminateProcess(info.hProcess, 1);
++      goto done;
++    }
++  }
++
++  /* Spawn succeeded. Beyond this point, failure is reported asynchronously. */
++
++  process->process_handle = info.hProcess;
++  process->pid = info.dwProcessId;
++
+   /* Set IPC pid to all IPC pipes. */
+   for (i = 0; i < options->stdio_count; i++) {
+     const uv_stdio_container_t* fdopt = &options->stdio[i];