TencentCloud / TencentCloud/Octop

[bug] Windows 上第二个用户打开工作台浏览器失败:Chrome did not start on localhost:9223

Open
#752 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
Dominant language
Python
Stars
4.2k
Forks
459
Avg merge
8h 36m
Merged PRs (30d)
228

Description

问题

Windows 上第二个用户打开工作台(Dashboard)浏览器时失败:

failed to attach browser profile 'user-2':
Chrome did not start on localhost:9223 after 20 attempts

日志中伴随:

WARNING harness_browser.cdp.launch_prep — Browser profile
...\browser-profiles\user-2 is not Chrome-safe;
using \tmp\harness-browser-profiles-0\user-2 (BROWSER_USE_PROFILES_DIR)

环境

  • Windows 10/11,普通用户(非提权)
  • Octop 1.0.0(harness-browser 0.7.8)
  • 两个账号:user-1 正常,user-2 必失败
  • 注:本机为管理员且已提权时问题同样复现,非权限问题

根因

harness_browser/cdp/launch_prep.py 两处平台缺陷:

  1. _probe_writable() 在 Windows 上也创建 symlink。Windows 普通用户没有
    SeCreateSymbolicLinkPrivilege,探测必然 OSError → 返回 False →
    ensure_profile_writable() 误判 profile 不可用并触发迁移。
  2. _alt_profiles_root() 返回 Path("/tmp/harness-browser-profiles-{uid}")
    在 Windows 上得到无盘符相对路径 \tmp\...,Chrome 无法将其作为
    --user-data-dir,因此启动失败。

另(可另行讨论,本 PR 未改):ensure_profile_writable() 迁移时会写入进程级
os.environ["BROWSER_USE_PROFILES_DIR"]harness_browser.settings.profiles_dir
会污染同一进程内后续其他用户的启动。

旁证(内部不一致):同一依赖链上的 octop/infra/browser/setup.py
_probe_dir_writable() 已明确在非 Linux 跳过 symlink 探测,且
_relocated_profiles_root_for_uid() 在非 Linux 使用 tempfile.gettempdir()
说明该写法是既定意图,launch_prep.py 未同步。

修复

  1. _probe_writable():仅在 os.name == "posix" 时执行 symlink 探测;
  2. _alt_profiles_root():非 POSIX 返回
    Path(tempfile.gettempdir()) / f"harness-browser-profiles-{USERNAME or USER or 'default'}"
  3. 新增 import tempfile

POSIX 行为完全不变(仍走 /tmp/harness-browser-profiles-<uid>,Linux 下是空操作)。

验证

  • git apply --check 通过;应用后与预期文件字节级一致
  • Windows 实测:修复前 user-2 报 Chrome did not start on localhost:9223
    修复后两账号并发正常,Chrome 分别以
    --user-data-dir=...\browser-profiles\user-1(9222)与 ...\user-2(9223)运行,
    日志不再出现 not Chrome-safe
  • Linux 回归:_probe_writable 仍执行 symlink 探测(调用次数 1→1),
    _alt_profiles_root() 输出不变

补丁(可直接应用,仅供定位参考):

# Fix: Windows CDP profile relocation to an invalid drive-relative path
#
# packages/harness_browser/cdp/launch_prep.py
#   1. _probe_writable(): skip the symlink probe on Windows. Normal Windows
#      users lack SeCreateSymbolicLinkPrivilege, so the probe always failed and
#      forced a bogus 'profile is not Chrome-safe' relocation.
#   2. _alt_profiles_root(): on Windows return an absolute temp path instead of
#      Path('/tmp/...'), which becomes a drive-relative '\tmp\...' that Chrome
#      cannot use as --user-data-dir.
#
# Symptom: 'failed to attach browser profile user-2: Chrome did not start on
# localhost:9223 after 20 attempts' when a second user opens the workbench
# browser on Windows.
#
# Apply with:  patch -p1 -d <repo-root> < octop-browser-win-fix.patch
#          or: git apply -p1 octop-browser-win-fix.patch
#
# Platform notes:
#   * POSIX (Linux/macOS) behaviour is UNCHANGED: the symlink probe still runs
#     and _alt_profiles_root() still returns /tmp/harness-browser-profiles-<uid>.
#     The patch is a no-op there; it is only needed on Windows (including
#     Windows Server, e.g. when Octop runs under a service account that cannot
#     create symlinks).
#   * Generated against harness-browser 0.7.8 (the version bundled with
#     Octop 1.0.0). Verify the file still matches before applying; if the
#     upstream file moved, re-apply the 3 edits manually.

--- a/packages/harness_browser/cdp/launch_prep.py
+++ b/packages/harness_browser/cdp/launch_prep.py
@@ -20,6 +20,7 @@
 import shutil
 import subprocess
 import sys
+import tempfile
 import time
 from pathlib import Path
 
@@ -69,18 +70,31 @@
         probe = directory / f".harness-write-{os.getpid()}"
         probe.write_text("ok", encoding="utf-8")
         probe.unlink()
-        # Chrome's ProcessSingleton creates a symlink; probe that too.
-        link = directory / f".harness-link-{os.getpid()}"
-        link.symlink_to("probe-target")
-        link.unlink()
+        # Chrome's ProcessSingleton creates a symlink; probe that too on
+        # POSIX. Windows normal users lack SeCreateSymbolicLinkPrivilege, so
+        # a failed symlink probe there does not mean Chrome cannot use the
+        # directory (and must not force a relocation).
+        if os.name != "nt":
+            link = directory / f".harness-link-{os.getpid()}"
+            link.symlink_to("probe-target")
+            link.unlink()
         return True
     except OSError:
         return False
 
 
 def _alt_profiles_root() -> Path:
-    uid = os.getuid() if hasattr(os, "getuid") else 0
-    return Path(f"/tmp/harness-browser-profiles-{uid}")
+    getuid = getattr(os, "getuid", None)
+    if callable(getuid):
+        return Path(f"/tmp/harness-browser-profiles-{getuid()}")
+    # Windows: never use a drive-relative ``\tmp\...`` path (Chrome resolves
+    # that against its own working directory). Use an absolute temp root and a
+    # stable per-user token so relocated profiles survive restarts.
+    token = (
+        (os.environ.get("USERNAME") or os.environ.get("USER") or "default").strip()
+        or "default"
+    )
+    return Path(tempfile.gettempdir()) / f"harness-browser-profiles-{token}"
 
 
 def _under_root_home(path: Path) -> bool:

根因在 harness-browser 0.7.8(Octop 仅通过依赖引入),请帮忙转到上游修复; harness-browser 尚未开源,补丁供定位参考

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with packages/harness_browser/cdp/launch_prep.py, focusing on _probe_writable() and _alt_profiles_root(); compare the related logic in octop/infra/browser/setup.py. Verify the Windows profile paths and POSIX regression behavior described in the issue, then coordinate the fix with the upstream harness-browser project because its source is not included here.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
devtools
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.