问题背景
先贴一下环境信息:
芯片: 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
命令,您猜怎么着,问题解决了。这一问题困扰了许久,而且有预感后续也会遇到,遂记录下来供自己/互联网上有同样疑问的朋友参考。
参考资料
排查中搜索了一些信息,把相对有启发作用的内容放到这里了: