Skip to content

App hangs silently on launch — main thread blocked by synchronous subprocess/IO #139

@1Ckpwee

Description

@1Ckpwee

问题描述

启动 CodeIsland 后,菜单栏岛消失,手动重新启动 app 没有任何反馈(无窗口、无报错),直到打开 Activity Monitor 才发现进程状态为 "Not Responding",必须手动 Force Quit 后重新打开才恢复。

macOS 不会自动为无响应的 app 弹出对话框,只会在 Activity Monitor 中静默标记,因此用户完全没有任何可见反馈。

根因分析

主线程上存在多处同步阻塞调用,任何一处卡住都会导致整个 app 无响应:

1. 启动时同步等待 claude --version 子进程(Critical)

位置: ConfigInstaller.swift:810-829detectClaudeVersion()

调用链:

AppDelegate.applicationDidFinishLaunching
  → ConfigInstaller.install()
    → installClaudeHooks()
      → compatibleEvents()
        → detectClaudeVersion()
          → Process().waitUntilExit()  // 主线程,无超时

如果 Claude CLI 响应慢、卡住、有权限弹窗、或路径异常,整个 app 在启动阶段就会挂起。

2. Terminal 激活时主线程同步等待子进程(Critical)

位置: TerminalActivator.swift:890-913runProcess()

从 SwiftUI 按钮回调(NotchPanelView.swift:950)和快捷键处理(AppDelegate.swift:198)直接在主线程调用。activateGhostty() 会连续调用多次 runProcess()(tmux 命令),每次都 waitUntilExit()

3. 周期性 hook 修复在主线程做文件 I/O(High)

位置: AppDelegate.swift:68-79

  • hookRecoveryTimer 每 300 秒触发一次 verifyAndRepair()
  • 每次其他 app 激活(NSWorkspace.didActivateApplicationNotification)也会触发
  • 同步读写 ~/.claude/settings.json~/.codex/hooks.json 等多个配置文件
  • 如果 home 目录在网络磁盘上,阻塞时间可能很长

建议修复方向

  1. detectClaudeVersion() 移到后台队列,加超时保护(如 5 秒)
  2. TerminalActivator.runProcess() 调用移到后台队列,主线程只负责 UI 更新回调
  3. verifyAndRepair() 移到后台队列,并加 debounce 避免频繁触发
  4. 所有 Process.waitUntilExit() 调用加超时保护
  5. 考虑增加 main thread watchdog,当主线程阻塞超过阈值时记录日志或提示用户

环境

  • macOS Sequoia
  • CodeIsland v1.0.23

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions