macOS launchd CPU 占用过高问题排查记录

8 阅读3分钟

macOS launchd CPU 占用过高问题排查记录

问题现象

MacBook 出现以下异常:

  • launchd CPU 长时间占用 100%~300%
  • logd CPU 也持续较高
  • 风扇高速运转(Intel Mac)或机器发热(Apple Silicon)
  • 即使退出 Cursor,CPU 仍然没有下降

最初怀疑:

  • Cursor
  • VSCode
  • 网络代理
  • 某个后台进程不断拉起

最终证明以上均不是根因。


排查过程

1. 查看 launchd

 top -o cpu

发现:

 launchd
 logd

长期排在 CPU 前列。


2. 查看 launchd 的 syscall

使用

 sudo fs_usage launchd

发现不停输出:

 lstat64 private/etc/localtime
 sendto()
 lstat64 private/etc/localtime
 sendto()
 ...

说明:

launchd 一直在:

  • 查询时区
  • 向某个 socket 发消息
  • 写日志

形成死循环。


3. 查看 launchd 打开的文件

 sudo lsof -p 1

发现:

 FD 5
 ​
 /private/var/log/com.apple.xpc.launchd/launchd.log

说明 launchd 正在疯狂写日志。


4. 查看 launchd 日志

 sudo tail -100 \
 /private/var/log/com.apple.xpc.launchd/launchd.log

发现大量重复内容:

 (gui/501/com.sogou.SogouTaskManager)
 ​
 cannot spawn:
 service plist has the quarantine extended attribute

紧接着:

 assertion failed

整个日志几乎全部由这一条组成。


根因分析

真正的问题不是 Cursor。

真正的问题是:

 com.sogou.SogouTaskManager

即:

搜狗输入法后台服务。

launchd 不断尝试启动它:

 launchd
         │
         ▼
 启动 SogouTaskManager
 ​
         │
         ▼
 启动失败
 ​
 原因:
 ​
 service plist has the quarantine extended attribute
 ​
         │
         ▼
 launchd 认为 KeepAlive 服务退出
 ​
         │
         ▼
 再次启动
 ​
         │
         ▼
 再次失败
 ​
 ...
 ​
 无限循环

于是:

 launchd CPU ↑
 ​
 ↓
 ​
 不停写日志
 ​
 ↓
 ​
 logd CPU ↑
 ​
 ↓
 ​
 整个系统 CPU 很高

为什么会失败?

日志中的关键错误:

 service plist has the quarantine extended attribute

说明:

LaunchAgent 或其对应文件带有:

 com.apple.quarantine

扩展属性。

这是 macOS 的安全机制。

通常来源:

  • 浏览器下载
  • AirDrop
  • 第三方安装包
  • 手动复制 App
  • 升级后遗留文件

launchd 检测到:

此服务处于 quarantine 状态,不允许启动。

但是 LaunchAgent 又配置了:

 KeepAlive = true

于是:

 失败
 ​
 ↓
 ​
 再次启动
 ​
 ↓
 ​
 再次失败
 ​
 ↓
 ​
 无限循环

为什么 logd 也会很高?

因为:

每次启动失败都会记录日志:

launchd

↓

syslog

↓

logd

↓

写 launchd.log

所以:

launchd CPU 高

↓

logd CPU 也高

这是结果,而不是原因。


Cursor 为什么不是根因?

虽然最开始怀疑 Cursor:

  • Cursor 经常启动大量后台进程
  • AI 插件可能频繁创建子进程

但是:

关闭 Cursor 后:

launchd CPU

没有下降

并且 launchd 日志全部指向:

com.sogou.SogouTaskManager

因此可以排除 Cursor。


后续排查建议

查看 LaunchAgent

launchctl print gui/501/com.sogou.SogouTaskManager

查找 plist

find ~/Library /Library \
-name "*SogouTaskManager*.plist" 2>/dev/null

通常位于:

~/Library/LaunchAgents/

或:

/Library/LaunchAgents/

查看 quarantine 属性

xattr -l \
~/Library/LaunchAgents/com.sogou.SogouTaskManager.plist

或者:

xattr -l /Applications/SogouInput.app

如果看到:

com.apple.quarantine

即可确认问题。


临时停止服务

launchctl bootout gui/501/com.sogou.SogouTaskManager

或者:

launchctl unload \
~/Library/LaunchAgents/com.sogou.SogouTaskManager.plist

如果 CPU 立即下降,则进一步验证问题来源。


修复方式

方法一(推荐)

重新安装最新版搜狗输入法。

这样可以同时修复:

  • LaunchAgent
  • plist
  • 权限
  • 签名
  • quarantine 状态

这是最稳妥的方法。


方法二

移除 quarantine 属性:

sudo xattr -dr \
com.apple.quarantine \
/Applications/SogouInput.app

或者:

xattr -d \
com.apple.quarantine \
~/Library/LaunchAgents/com.sogou.SogouTaskManager.plist

仅建议在确认文件来源可信时使用。


排查思路总结

CPU 高
    │
    ▼
launchd 高
    │
    ▼
查看 syscall
(fs_usage)
    │
    ▼
不停 sendto()
不停 lstat()
    │
    ▼
查看 lsof
    │
    ▼
发现 launchd.log
    │
    ▼
查看日志
    │
    ▼
发现:

com.sogou.SogouTaskManager

cannot spawn

service plist has the quarantine extended attribute

    │
    ▼
确定:

LaunchAgent 无限重启

    │
    ▼
launchd CPU 高

    │
    ▼
logd CPU 高

结论

本次问题的直接原因是:

搜狗输入法(com.sogou.SogouTaskManager)对应的 LaunchAgent 无法启动,因为其 plist(或关联文件)带有 com.apple.quarantine 扩展属性。由于 LaunchAgent 配置了自动保活(KeepAlive),launchd 持续尝试重启该服务,导致陷入无限重启循环,从而造成 launchdlogd CPU 长时间占用过高。

Apple 的 launchd 会负责管理 LaunchAgent/LaunchDaemon,当配置了保活策略时,只要服务异常退出,就会持续尝试重新启动。若启动失败的原因(如 quarantine、签名、权限等)一直存在,就会形成重启风暴(restart storm)。相关行为与 launchd 的服务管理机制一致。