diff --git a/App/lib/core/BuildPipeline.vp b/App/lib/core/BuildPipeline.vp index dc0667b..acf1d82 100644 --- a/App/lib/core/BuildPipeline.vp +++ b/App/lib/core/BuildPipeline.vp @@ -9,6 +9,8 @@ import vthreading import w32.fileio as fileio import w32.win32file import w32.win32base +import w32.win32process as win32process +import w32.win32sync as win32sync import subprocess import viperlib import ast @@ -506,6 +508,44 @@ def free_llc_task(task: LlcTask | t.CPtr): task.ModuleSha1 = None +def _run_cmd_wait(cmd: str) -> int: + """CreateProcessA 同步执行命令并等待退出,返回退出码。 + + 替代 stdlib.system:Windows asan 环境下 cmd /c 经 CreateProcess 受 + RTL allocator hook 干扰可能挂起(LLVM issue #111166 同类,ClassArrayTest + llc 固定卡死根因);CreateProcessA 直接执行目标程序并继承父进程控制台 + (stdout/stderr 直接显示,同 system 语义)。全 stdlib.malloc/栈分配, + worker 线程安全。 + """ + if cmd is None: + return -1 + cl_len: t.CSizeT = string.strlen(cmd) + cmd_line: bytes = stdlib.malloc(cl_len + 1) + if cmd_line is None: + return -1 + string.strcpy(cmd_line, cmd) + sa: w32.win32base.SECURITY_ATTRIBUTES = w32.win32base.SECURITY_ATTRIBUTES() + si: win32process.STARTUPINFOA = win32process.STARTUPINFOA() + pi: win32process.PROCESS_INFORMATION = win32process.PROCESS_INFORMATION() + sa.nLength = w32.win32base.SECURITY_ATTRIBUTES.__sizeof__() + sa.lpSecurityDescriptor = t.CPtr(0) + sa.bInheritHandle = 1 + si.cb = win32process.STARTUPINFOA.__sizeof__() + # create_flags=0:子进程继承父控制台(输出直接显示,同 system 语义) + ok: int = win32process.CreateProcessA( + t.CPtr(0), cmd_line, t.CPtr(0), t.CPtr(0), 1, 0, + t.CPtr(0), t.CPtr(0), t.CPtr(c.Addr(si)), t.CPtr(c.Addr(pi))) + stdlib.free(cmd_line) + if ok == 0: + return -1 + win32sync.WaitForSingleObject(pi.hProcess, w32.win32base.INFINITE) + exit_code: t.CUInt32T = 0 + win32process.GetExitCodeProcess(pi.hProcess, t.CPtr(c.Addr(exit_code))) + w32.win32base.CloseHandle(pi.hProcess) + w32.win32base.CloseHandle(pi.hThread) + return t.CInt(exit_code) + + def _llc_task_worker(arg: t.CPtr) -> t.CPtr: """llc 线程入口:只调 stdlib.system(),不做任何分配(线程安全) Result 仅在命令链执行完后写入(初始 -1;join 超时保持 -1 → 报失败)""" @@ -518,14 +558,14 @@ def _llc_task_worker(arg: t.CPtr) -> t.CPtr: (task.LlcCmd if task.LlcCmd is not None else "?")) #endregion if task.OptCmd is not None: - opt_rc: int = stdlib.system(task.OptCmd) + opt_rc: int = _run_cmd_wait(task.OptCmd) #region debug-point LLC1 stdio.printf("[LLC-DBG] opt rc=%d\n", opt_rc) #endregion if opt_rc != 0: task.Result = 1 return t.CPtr(0) - llc_rc: int = stdlib.system(task.LlcCmd) + llc_rc: int = _run_cmd_wait(task.LlcCmd) #region debug-point LLC2 stdio.printf("[LLC-DBG] llc rc=%d sha1=%s\n", llc_rc, (task.ModuleSha1 if task.ModuleSha1 is not None else "?"))