diff --git a/patches/node/.patches b/patches/node/.patches index 48691cc53987..548b3ad9d73d 100644 --- a/patches/node/.patches +++ b/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 diff --git a/patches/node/win_process_avoid_assert_after_spawning_store_app_4152.patch b/patches/node/win_process_avoid_assert_after_spawning_store_app_4152.patch new file mode 100644 index 000000000000..ff3ed47f1d9d --- /dev/null +++ b/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 +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];