目 录CONTENT

文章目录

wslc ps 卡死的排查:一次「停容器不停 VM」引发的连环故障

DarkAthena
2026-10-31 / 0 评论 / 0 点赞 / 0 阅读 / 0 字

wslc ps 卡死的排查:一次「停容器不停 VM」引发的连环故障

背景

前两天在 WSL 里跑着几个容器,用完正常把它们全停了。结果再执行 wslc ps -a 就彻底卡住了:

$ wslc ps -a
(光标闪烁,无输出、无报错、无超时)

不报错也不返回,就那么挂着。这种故障最烦人,因为你连错误信息都没有。

环境

项目值
Windows11 26H2,build 26300.9711
WSL / wslc3.0.3.0
WSL 内核6.18.54.1-1

先搞清楚 wslc 到底是个啥

排查的第一步不是动手,是搞明白你面对的是什么。

wslc 并不是 wsl.exe 的一个子命令。它是 WSL 3.x 的容器 CLI,一个独立的可执行文件:

C:\Program Files\WSL\wslc.exe
  InternalName:     wslc.exe
  FileDescription:  Windows Subsystem for Linux Container CLI
  FileVersion:      3.0.3.0

同目录还有个 wslcsession.exe(Description:Windows Subsystem for Linux Containers User Session),它是会话管理器,以 -Embedding 方式挂在 svchost 下的 COM 服务。

每个 Session 有独立的虚拟磁盘,放在 %LOCALAPPDATA%\wslc\sessions\<会话名>\ 下面,我这里是 54.4GB 的 storage.vhdx。

排查过程

第一步:找到「能返回」和「不能返回」的分界线

这是整个排查里最有价值的一步。把能跑的命令都跑一遍,结果非常整齐:

命令结果是否需要进会话
wslc version秒回否
wslc --help秒回否
wslc info秒回否
wslc system session list秒回否
wslc ps -a无限卡住是
wslc images无限卡住是

分界线清清楚楚:不依赖 Session 的命令全部正常,凡是要进 Session 干活的,全部挂死。

于是怀疑范围一下就缩小到了「会话层」,而不是网络、不是安装损坏、不是内核。

为了再确认一下不是网络问题,我把卡住的进程抓下来看了它的连接:

=== 该进程的网络连接 ===
(无 TCP/UDP 连接)

零连接。它是卡在本地 IPC 上等一个永远不会来的响应,跟网络、跟 HTTP 代理一点关系没有。

第二步:僵尸会话

既然怀疑会话层,就看会话:

$ wslc system session list
ID        创建者 PID   显示名称
1         82928     wslc-cli-DarkAthena

有个 Session 1,创建者 PID 是 82928。拿这个 PID 去查:

PS> Get-Process -Id 82928
>>> 不存在!会话创建者进程已消失 —— 僵尸会话确认

破案了。Session 的宿主进程早就没了,但会话管理器 wslcsession.exe 的账本里还把它列为活动会话。 所有命令进去执行,就在那儿干等着一个死人回话,自然永远不会返回。

这也解释了第一步的分界线:wslc info 只是问会话管理器要个清单,管理器自己能答;wslc ps 是要 Session 干活的,Session 是死的,自然挂死。

第三步:还有一把锁

按说把僵尸会话清掉就该好了。执行官方命令试试:

$ wslc system session terminate
(卡住,30s 无响应)

有意思,terminate 自己也卡住了——它同样得先进会话,典型的死锁。干掉它,直接送 wslcsession.exe 上路(COM 服务,杀掉会自动重新激活一个干净的):

PS> Stop-Process -Id 85468 -Force

再看会话表,干净了:

$ wslc system session list
ID        创建者 PID   显示名称
(空)

兴冲冲跑 wslc ps -a,这次不卡了,4 秒返回,但是甩出来一个新错误:

$ wslc ps -a
另一个程序正在使用此文件,进程无法访问。
错误代码: ERROR_SHARING_VIOLATION

第二层故障浮出水面:54.4GB 的 storage.vhdx 被别的进程独占锁着,新 Session 根本挂不上盘。

谁干的?看进程:

wslcsession.exe   22388
vmcompute.exe     16184
vmwp.exe          69116    创建于 2026/10/28 15:02:44,父进程 vmcompute

关键在这儿——我本机 4 个发行版全都是 Stopped:

  NAME                    STATE           VERSION
* Ubuntu-24.04            Stopped         2
  rancher-desktop         Stopped         2
  rancher-desktop-data    Stopped         2
  Ubuntu-26.04            Stopped         2

发行版全停了,却有个 vmwp(虚拟机工作进程)还活着。再看时间戳,严丝合缝:

证据时间
vmwp PID 69116 创建(父进程 vmcompute)10/28 15:02:44
会话 swap.vhdx 写入10/28 15:02:46

vmwp 69116 就是那个僵尸 Session 的虚拟机,它从 10/28 起一直攥着磁盘不松手。

权限的天花板

剩下的事就是把这个 vmwp 弄走。于是有了这张很说明问题的表:

手段结果原因
taskkill /F /PID 69116拒绝访问vmwp 是 PPL 受保护进程,管理员也杀不掉
Get-VM / Stop-VM不可用本机没装 Hyper-V 管理工具,vmms 服务也不存在
Stop-Service vmcompute -Force卡在「正在停止」,停不下来服务要停时得等 VM worker 清理,而那个 worker 卡着,两边互等
wsl --shutdown1 秒返回,无效wslc 的 Session VM 不在 wslservice 账本里,wsl -l -v 压根看不见它
杀 wslcsession.exe成功用户态 COM 服务,可重建

这张表里最有意思的是 wsl --shutdown 那一行。wslc 的会话虚拟机压根不在 wslservice 的管理范围内,所以 wsl -l -v 永远列不出来它,常规的 WSL 排障手段一个都够不着它。这也是这类故障难查的根源——所有熟悉的命令都告诉你「一切正常」。

最后 Stop-Service vmcompute 卡在「正在停止」出不来,没辙,重启机器,一了百了。重启后 wslc ps -a 恢复正常,50GB 盘里的镜像和容器都还在,数据无损。

复盘:那 1.5GB 内存到底该不该管

回到开头。故障当天下午我是这么操作的:正常停掉所有 wslc 容器之后,发现任务管理器里 vmmemwslc-cli-DarkAthena 进程还占着不少内存,过了几个小时还有 1.5GB。于是尝试在任务管理器里结束它,报错,没结束成功,就先没管了。

先回答一个问题:这个 kill 操作是不是故障的直接原因?

按最简单的逻辑分析,它是一个「失败的操作」,理论上没改变任何状态。而且 vmmem* 这类进程本身也是受保护的,任务管理器结束不掉很正常。所以我倾向于认为它不是直接凶手。

但它绝不是无关操作,因为它暴露的东西才是真正的根因。

要点有三个:

1. 停容器不等于停 VM。

vmmemwslc-cli-DarkAthena 这个进程,本质上是 Windows 给这个虚拟化工作负载做的「内存记账」载体,它在任务管理器里代表 Session VM 占了多少内存。停掉容器只是让 VM 里没进程跑了,VM 本身还活着,内存自然不释放。

也就是说,「停了容器还占 1.5GB」不是内存泄漏,是** VM 压根没关**。而我盯着的那个 storage.vhdx 锁,正是这同一台没关的 VM 持有的。

2. 宿主进程退出了,VM 却留下了。

会话创建者 PID 82928 在故障发生前就已经不存在了。这是个拉胯的地方:宿主进程退出时没有把 VM 一并收走,VM 成了孤儿,而会话管理器账本里那条记录也没有被清理。两边一脱节,僵尸会话就这么诞生了。

至于 82928 究竟是什么时候死的、死在什么环节,进程已消失无从追溯,这部分我只能猜想。

3. 别去 kill vmmem。

既杀不掉(受保护),即使能杀掉也没用——它只是个记账的表象,真正的实体是 vmwp 托管的虚拟机。想释放,得从虚拟机这一层动手。

那正确的释放姿势是什么?

# 停容器之后,要释放资源得显式终止会话
wslc system session terminate

注意,实测本机 wsl --shutdown 对这个 Session VM 是无效的(前面那张表),别指望它。

总结

一句话:这次故障的根子是 wslc 停容器不停 VM,宿主进程退出后 VM 与会话记录两边脱节,产出「僵尸会话 + 磁盘锁」的连环套,最终让所有进会话的命令永久挂起。

几条实用建议:

  • 排查判定:wslc info 秒回而 wslc ps 卡死,基本可以锁定是会话层故障,别往网络、代理、重装上浪费时间。
  • 判定僵尸:wslc system session list 拿到创建者 PID,看它是否还活着,非常好使。
  • 释放资源:用完容器想回收内存,走 wslc system session terminate,别手动去 kill vmmem*,杀不掉也没用。
  • 兜底手段:万一走到 vmwp 持锁这一步,vmcompute 停不下来就直接重启。记得先把 wslcsession.exe 清掉,让它重建干净的会话表。

最后说句实在的,wslc 这个东西在 wsl -l -v 里完全隐身,wsl --shutdown 又管不着它,出了问题所有熟悉的命令都说「一切正常」。这算不上 bug,但对排查的人来说确实不太友好。恐怕后面 WSL 得把这层账本也纳进统一管理,不然同类的问题还会再来一遍。

本文仅代表个人排查过程,环境为 Windows 11 26H2 + WSL/wslc 3.0.3.0,不同版本表现可能有差异。

0
  1. 支付宝打赏

    qrcode alipay
  2. 微信打赏

    qrcode weixin
博主关闭了所有页面的评论