家里的电脑已经活了 8 年了,上面搭载的 NVIDIA 1050 显卡已经陈旧过时。最近(指三个月前),nvidia 新版本驱动把 1050 驱动支持给丢掉了,我在无脑 Syu 过程中被坑了。
背景 自从不折腾技术以后,我的 Arch 系统更新是半年更新一次(我手上另一台 NixOS 已经是 2023 年的版本了),即如果不是 Chrome 实在太老老到有网站不服务我了,我都不会选择更新。
缘起 今天要开一个腾讯会议,我之前(2月份)因为某些原因 Syu 了但是没重启,然后发现腾讯会议打不开,查了一下说是内核版本对不上,于是开始继续 Syu 加重启。
重启后,发现能进桌面,但是不能 HDMI 投屏,初步怀疑是 nvidia driver 哪里又挂了,首先把 modsetting 用的 conf 重新抄了一遍,发现不工作。
包管理 遇到这种问题,需要查阅 archlinux.org。好在 archlinux.org 告诉我最近确实有 breaking changes: 从 590 之后,nvidia-lts 包变成 nvidia-open-lts 了。
于是我吭哧吭哧去装 AUR 的 nvidia-580xx-dkms,安装过程中发现有很多文件存在覆盖不了,我没细看就直接 --overwrite="*" 过去了。结果重启发现还是不行。
Xorg 和 MESA 吗 于是开始查看 Xorg.log,发现最后竟然有一段 segfault
1 2 3 4 (EE) unw_get_proc_name failed: no unwind info found [-10] [ 1282.613] (EE) 0: /usr/lib/Xorg (?+0x0) [0x5582c7bd0654] [ 1282.614] (EE) unw_get_proc_name failed: no unwind info found [-10] [ 1282.614] (EE) 1: /usr/lib/libc.so.6 (?+0x0) [0x7f11e3a032d0]
一细看 journalctl,发现如下 log
1 2 3 4 5 6 7 8 9 10 Stack trace of thread 937: #0 0x000074eafb653f32 n/a (libc.so.6 + 0x9ef32) #1 0x000074eafb64839c n/a (libc.so.6 + 0x9339c) #2 0x000074eafb64868c n/a (libc.so.6 + 0x9368c) #3 0x000074eafb64ae5e pthread_cond_wait (libc.so.6 + 0x95e5e) #4 0x000074eaefdec55e n/a (libgallium-26.0.1-arch1.1.so + 0x5ec55e) #5 0x000074eaefda18fd n/a (libgallium-26.0.1-arch1.1.so + 0x5a18fd) #6 0x000074eaefdec49d n/a (libgallium-26.0.1-arch1.1.so + 0x5ec49d) #7 0x000074eafb64b97a n/a (libc.so.6 + 0x9697a) #8 0x000074eafb6cf2bc n/a (libc.so.6 + 0x11a2bc)
这是新 MESA 给我整活吗,然后去找了一下,没啥线索。
在此期间,我也尝试直接从 /var/cache/pacman 里面把去年八月份的包翻出来
1 2 3 4 5 6 pacman -U --overwrite="*" \ nvidia-lts-1:580.76.05-5-x86_64.pkg.tar.zst \ lib32-nvidia-utils-580.76.05-1-x86_64.pkg.tar.zst \ nvidia-utils-580.76.05-4-x86_64.pkg.tar.zst \ linux-lts-6.12.44-1-x86_64.pkg.tar.zst \ linux-lts-headers-6.12.44-1-x86_64.pkg.tar.zst
还是不成功(记住这个 overwrite 的伏笔)。
上 GDB 实在受不了了,直接开始 gdb /var/lib/Xorg.wrap,得到如下 log
1 2 3 4 5 6 7 8 9 10 11 12 13 #0 0x0000000000000000 in ?? () #1 0x0000746df6823035 in ?? () from /usr/lib/libnvidia-eglcore.so.590.48.01 ... #5 0x0000746df67f6e3f in NvGlEglApiInit () from /usr/lib/libnvidia-eglcore.so.590.48.01 ... #10 0x0000746dffcfcef9 in ?? () from /usr/lib/libEGL_nvidia.so.0 #11 0x0000746e0ce64946 in loadEGLExternalPlatform () from /usr/lib/libnvidia-egl-wayland.so.1 #12 0x0000746dffd6cfe2 in ?? () from /usr/lib/libEGL_nvidia.so.0 ... #20 0x0000746dffd1007d in ?? () from /usr/lib/libEGL_nvidia.so.0 #21 0x0000746e0cf12a64 in ?? () from /usr/lib/libEGL.so.1 #22 0x0000746e0cf1312c in ?? () from /usr/lib/libEGL.so.1 #28 0x0000746e15527c63 in ?? () from /usr/lib/xorg/modules/drivers/modesetting_drv.so
呃,哪来的 590??? 我于是去 /usr/lib 下面翻,发现不仅有 590xx,还有个 580.126(那个 580xx-dkms 带来的),而我包管理装的是 580.76。所有的主要的 so 直接指向了最新的 590。
到现在修法就很简单,直接在 /usr/lib 下面
然后重装 nvidia-lts,并把内核和 nvidia 全部加到 pacman.conf 的 IgnorePkg 中防止下次折腾。
顺便一提,/usr/lib/ 下面有所有版本的 nvidia so,怎么包管理都不记得清理它们的。