macOS 命令行指令 killed 问题排查

macOS 命令行指令 killed 问题排查

在本文中,作者分享了在 Apple M2 Pro 芯片、32GB 内存以及 macOS 15.0 Beta 版环境下遇到的 golangci-lint 工具被系统强制终止的问题。起初,作者怀疑版本落后,于是尝试通过重新安装来解决,但无论如何运行 golangci-lint,都会被系统以 SIGKILL 信号终止。进一步排查系统日志发现,问题出在 macOS 的代码签名机制。由于最新的 macOS 版本不再支持通过 spctl 命令禁用 Gatekeeper,作者最终通过重新签名 golangci-lint 解决了问题。本文记录了这一过程,供有类似问题的读者参考。

问题背景

先贴一下环境信息:

芯片: Apple M2 Pro

内存: 32 GB

macOS: 15.0 Beta版(24A5289g)

虽然猜测是 macOS beta 干的好事,但是排查下来也没有直接证据表明是其产生的,按照正常问题排查的流程来记录了。

起初,是作者在正常的牛马生活中,完成了一个需求,正常的按流程进行工作,突然间发现 golangci-lint 版本落后了,需要更新。遂使用下面的命令重装 golangci-lint

rm $(which golangci-lint) # 删除现有的 golangci-lint
go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.54.2 # 编译安装 1.54.2 版本,它支持 go1.21

作者以为就如同往常一样,静待编译完成后就可以高兴使用 golangci-lint 来屎里淘金时,变故发生了(隐藏了一些无关紧要的信息):

  ~/.../project on   branches/branch *4 !4 ?2 at  13:53:09
❯ golangci-lint version
[1]    2221 killed     golangci-lint version

并且,无论是使用任何参数(正确的或者不正确的),都是上面的结果。

排查过程

出现了上面的情况,遂怀疑是不是出门没看黄历,权限不够,但是加了 sudo 执行依旧如此。此时就很显然不是正常的问题了。

第一反应是去拷打 GPT 或者 GLM,它也回答了些无关痛痒的方法,即 重试重启重装 三件套,但是并不能解决问题。只能自己去探索到底发生什么事情了。不难观察到,这是被系统 killed 掉的状态,下意识就是去检查被 killed 的系统日志信息:

  ~/.../project on   branches/branch *4 !4 ?2 at  13:58:05
❯ sudo dmesg | grep -i kill >> kill.out

输出文件的内容如下:

[  345.501730]: igmp_input_v2_report: process v2 report on ifp en0CODE SIGNING: cs_invalid_page(0x104114000): p=3004[golangci-lint] final status 0x23020200, denying page sending SIGKILL
[  345.704416]: igmp_input_v2_report: process v2 report on ifp en0igmp_input_v2_report: process v2 report on ifp en0igmp_input_v2_report: process v2 report on ifp en0CODE SIGNING: cs_invalid_page(0x10480c000): p=3010[golangci-lint] final status 0x23020200, denying page sending SIGKILL
[  346.528375]: igmp_input_v2_report: process v2 report on ifp en0CODE SIGNING: cs_invalid_page(0x104518000): p=3016[golangci-lint] final status 0x23020200, denying page sending SIGKILL
[  347.469905]: CODE SIGNING: cs_invalid_page(0x10014c000): p=3022[golangci-lint] final status 0x23020200, denying page sending SIGKILL
[  347.653755]: igmp_input_v2_report: process v2 report on ifp en0igmp_input_v2_report: process v2 report on ifp en0CODE SIGNING: cs_invalid_page(0x10452c000): p=3026[golangci-lint] final status 0x23020200, denying page sending SIGKILL

相信各位聪明的读者是看懂了吧,是吧!作者在拷打了一下 GPT 后,得到的提示信息如下:

从你的日志输出来看,golangci-lint 被 macOS 的代码签名机制(Code Signing)所阻止。这通常是因为 macOS 检测到某些代码页面无效,并因此终止了进程。

这似乎是我们的老熟人了,我的工作电脑并没有关闭 SIP 并且允许未经签名的代码运行,现在看起来似乎得退让一下了。可以用烂熟于心的下面的指令启用系统隐藏的「允许所有程序在我的电脑上运行」选项。但是随着回车的敲下,输出的内容并不如作者心中所想:

  ~/.../project on   branches/branch *4 !4 ?2 at  13:58:30
❯ sudo spctl --master-disable
This operation is no longer supported. To disable the assessment subsystem, please use configuration profiles.

此时大大的问号从作者小小的脑袋中升起,这又是什么东西,祖宗之法失效了,再去拷打 GPT:

在 macOS 的最新版本中,Apple 已经禁用了通过 spctl 命令来禁用 Gatekeeper 的方法。你可以使用配置描述文件(Configuration Profiles)来管理这些设置。以下是如何创建和部署一个配置文件来禁用 Gatekeeper:

你需要创建一个 .mobileconfig 文件来配置 Gatekeeper 设置。

1. 打开文本编辑器并创建一个新的文件,内容如下:

省略1万字

2. 保存文件为 GatekeeperConfig.mobileconfig

省略给 golangci-lint 提 issue/pr 的不过脑子的建议

看着就头疼,遂换一个思路,既然是签名问题,那么我来给它签不就完了吗:

  ~/.../project on   branches/branch *4 !4 ?2 at  14:00:05
❯ sudo codesign --force --deep --sign - $(which golangci-lint)
.../go/bin/golangci-lint: replacing existing signature

随着回车的敲下,然后重新执行 golangci-lint 命令,您猜怎么着,问题解决了。这一问题困扰了许久,而且有预感后续也会遇到,遂记录下来供自己/互联网上有同样疑问的朋友参考。

参考资料

排查中搜索了一些信息,把相对有启发作用的内容放到这里了:

https://blog.csdn.net/m0_46958731/article/details/138999711

https://blog.51cto.com/u_15366127/5622274

Comment