fix(phase2): llc worker 改用 CreateProcessA 替代 system,修 asan 并发挂起
插桩证实:ClassArrayTest 固定 llc 失败是 e5fb16127bce8f68 的 worker 卡在 stdlib.system() 内(LLC2 未打印,Result 保持 -1)。Python 复现 os.system 并发无问题,差异仅剩 asan 构建环境——Windows asan 的 RTL allocator hook 经 CreateProcess 启动子进程时受干扰(LLVM issue #111166 同类)。 新增 _run_cmd_wait:CreateProcessA 直接执行 + WaitForSingleObject + GetExitCodeProcess,继承父控制台输出(同 system 语义),全 stdlib/栈分配 线程安全。含 [LLC-DBG] 插桩,验证后移除。
This commit is contained in:
1 parent
f3c94917e5
commit
70c88107ce
1 file changed
+42
-2
@@ -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 "?"))
|
||||
|
||||
Reference in new issue
Block a user