diff --git a/web_server.py b/web_server.py index f4c726c..d1892d8 100644 --- a/web_server.py +++ b/web_server.py @@ -84,14 +84,30 @@ _UIAUTO_PID_FILE = os.path.join( _uiauto_proc = None +def _pid_cmdline_has(pid, keyword): + """校验 PID 对应的进程命令行含 keyword(容器重启后 PID 复用会误杀, + 杀前必须确认目标真是残留的 uiautodev,而不是 MCP/web 等其它进程)。""" + try: + with open(f"/proc/{pid}/cmdline", "rb") as f: + cmd = f.read().replace(b"\x00", b" ").decode(errors="replace") + return keyword in cmd + except Exception: + return False + + def _kill_stale_uiauto(): - """清理上次 web_server 残留的 uiautodev 进程(读取 PID 文件)。""" + """清理上次 web_server 残留的 uiautodev 进程(读取 PID 文件)。 + + 容器重启后 PID namespace 重建、PID 会被复用(MCP/其它进程可能拿到与 + uiauto.pid 相同的值),因此 kill 前先校验命令行确为 uiautodev,防止 + 误杀同容器内的 MCP server 等进程导致连锁崩溃。 + """ if not os.path.exists(_UIAUTO_PID_FILE): return try: with open(_UIAUTO_PID_FILE) as f: pid = int(f.read().strip()) - if pid > 0 and pid != os.getpid(): + if pid > 0 and pid != os.getpid() and _pid_cmdline_has(pid, "uiautodev"): try: os.kill(pid, 0) # 探测进程是否存活 os.kill(pid, 15) # 终止残留