xfyyzy

摘要

问题现象 FreeBSD 小版本升级后 pkg 出现 Segfault 崩溃。

根本原因

  • freebsd-update 只升级 base system,不处理 /usr/local 下的第三方软件
  • 升级后原有的 pkg 是为旧版本系统编译的,在新环境下运行触发 ABI 不兼容
  • 这不是升级流程的问题,而是 pkg 与新系统不匹配导致

解决方案

  • 升级完成后立即使用 pkg-static 重新安装 pkg,然后升级所有软件包
  • 大版本升级建议强制重建所有包

验证方法

  • 检查 freebsd-version 的三个版本(kernel/running/userland)是否一致
  • 确认 pkg 的 ABI 与系统匹配

标准升级流程回顾

freebsd-update -r 14.3-RELEASE upgrade
freebsd-update install
reboot
freebsd-update install

这是官方推荐的小版本升级流程:

  1. upgrade - 准备升级数据,不改动当前系统
  2. 第一次 install - 安装新内核
  3. 重启
  4. 第二次 install - 安装新 userland,合并 /etc

第三次 install 仅在系统提示需要删除旧共享库时才需要。

为什么 pkg 会 Segfault

关键点:freebsd-update 只管 base system(/bin/sbin/lib/usr/lib、内核等),不处理 /usr/local 下的内容。

升级到 14.3 后:

  • base system 已是 14.3,对应新的库和 syscall
  • 原 14.2 安装的 pkg 仍是旧版本,按旧库编译链接
  • 旧 pkg 在新环境运行时可能触发 ABI 不兼容或 bug

从源码重新安装 pkg 后问题消失,说明是 pkg 与新系统不匹配,而非 base 升级失败。

升级后应执行的步骤

小版本升级完成后:

pkg-static install -f pkg
pkg upgrade

大版本升级建议强制重建所有包:

pkg-static install -f pkg
pkg upgrade -f

验证系统状态

# 三个版本应一致
freebsd-version -kru

# 当前内核
uname -mr

# pkg 版本
pkg -v

# 确认 ABI 匹配(如 FreeBSD:14:amd64)
pkg -vv | egrep 'ABI|url'

排除 base 升级不完整

若出现以下情况可能导致 base 半新半旧:

  • freebsd-update install 中途报错退出
  • 第一次 install 后未重启就执行其他操作
  • 升级时磁盘/内存故障

但如果系统能正常启动,仅 pkg 相关操作崩溃,重新编译 pkg 后恢复正常,则更符合 pkg 自身问题的特征。

结论

  • 升级流程本身没有问题
  • pkg segfault 是旧版本 pkg 与新 base 不兼容导致
  • 从源码重装 pkg 等价于为新系统编译匹配版本
  • 升级后及时执行 pkg-static install -f pkg && pkg upgrade 可避免此类问题