From ebfaacf7bf931d381e3171f51bb3d4912785c2d1 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Sat, 22 Aug 2026 07:31:06 +0800 Subject: [PATCH] =?UTF-8?q?fix(tpc):=20worker=20cProfile=20=E9=BB=98?= =?UTF-8?q?=E8=AE=A4=E7=A6=81=E7=94=A8=E2=80=94=E2=80=94=E7=8E=AF=E5=A2=83?= =?UTF-8?q?=E5=8F=98=E9=87=8F=20TPC=5FWORKER=5FPROF=3D1=20=E5=BC=80?= =?UTF-8?q?=E5=90=AF?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 之前 getprofile 互斥检查仍冲突(用户环境仍报 Another profiling tool is already active,viztracer --log_multiprocess 场景) - 彻底修复:cProfile 默认不启用(TPC_WORKER_PROF=1 显式开启才启用),与 viztracer 等外部 profiler 完全解耦;开启时仍有 getprofile 让位 + enable 异常兜底双保险 - 冲突根源:Python 只允许一个 profiling tool 活跃,TPC worker cProfile.enable() 检测到 viztracer 注入的 profiler 即抛错 -> worker 崩溃 -> batch 异常 -> 编译终止 --- lib/Projectrans/Phase2Translator.py | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/lib/Projectrans/Phase2Translator.py b/lib/Projectrans/Phase2Translator.py index 4a7bf45..355d4af 100644 --- a/lib/Projectrans/Phase2Translator.py +++ b/lib/Projectrans/Phase2Translator.py @@ -288,14 +288,18 @@ def _ProfileWorker(_fn): def _wrapper(*args, **kwargs): _prof = None try: - # 互斥:viztracer 等外部 profiler 已激活(sys.getprofile() 非 None)时 - # 跳过 cProfile——Python 只允许一个 profiling tool 同时活跃, - # cProfile.enable() 会抛 "Another profiling tool is already active" - # → worker 崩溃 → batch 异常 → 编译终止(viztracer --log_multiprocess 场景)。 - # 此时让 viztracer 独占记录,正常编译(无外部 profiler)仍保留 cProfile。 - if sys.getprofile() is None: + # cProfile 默认不启用(环境变量 TPC_WORKER_PROF=1 开启): + # Python 只允许一个 profiling tool 同时活跃,TPC 的 cProfile 与 + # viztracer --log_multiprocess 冲突(cProfile.enable() 检测到已激活 + # profiler 抛 "Another profiling tool is already active" → worker 崩溃 + # → batch 异常 → 编译终止)。外部 profiler 活跃(sys.getprofile() + # 非 None)时即使开启也跳过让位;enable() 异常兜底吞掉保编译。 + if os.environ.get('TPC_WORKER_PROF', '0') == '1' and sys.getprofile() is None: _prof = cProfile.Profile() - _prof.enable() + try: + _prof.enable() + except RuntimeError: + _prof = None return _fn(*args, **kwargs) finally: if _prof is not None: