最近有台设备意外关机重启,经过磁盘文件损坏修复,可以成功进入系统。但是执行更新命令的时候报错 Segmentation fault (core dumped),如下:
|
1 2 3 4 5 6 7 8 9 10 |
$ sudo apt-get update 命中:1 http://security.ubuntu.com/ubuntu noble-security InRelease 命中:2 http://mirrors.tuna.tsinghua.edu.cn/ubuntu noble InRelease 命中:3 http://mirrors.tuna.tsinghua.edu.cn/ubuntu noble-updates InRelease 命中:4 http://mirrors.tuna.tsinghua.edu.cn/ubuntu noble-backports InRelease 错误:已到超时限制 Segmentation fault (core dumped) 正在读取软件包列表... 完成 E: Problem executing scripts APT::Update::Post-Invoke-Success 'if /usr/bin/test -w /var/lib/command-not-found/ -a -e /usr/lib/cnf-update-db; then /usr/lib/cnf-update-db > /dev/null; fi' E: Sub-process returned an error code |
观察输出日志,锁定文件 /usr/lib/cnf-update-db,于是查看文件内容,发现是个 Python3 的脚本,里面的内容如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
$ cat /usr/lib/cnf-update-db #!/usr/bin/python3 import apt_pkg import glob import logging import os import sys from CommandNotFound.db.creator import DbCreator from CommandNotFound import CommandNotFound if __name__ == "__main__": if "--debug" in sys.argv[1:]: logging.basicConfig(level=logging.DEBUG) elif "--verbose" in sys.argv[1:]: logging.basicConfig(level=logging.INFO) apt_pkg.init_config() db = CommandNotFound.dbpath if not os.access(os.path.dirname(db), os.W_OK): print("datbase directory %s not writable" % db) sys.exit(0) if apt_pkg.config.find_b("Acquire::IndexTargets::deb::CNF::DefaultEnabled", True): command_files = glob.glob("/var/lib/apt/lists/*Commands-*") else: command_files = glob.glob("/var/lib/apt/lists/*Contents*") if len(command_files) > 0: umask = os.umask(0o22) col = DbCreator(command_files) col.create(db) os.umask(umask) else: print("Could not find any command metadata") print("Please run 'apt update' before using this command.") |
于是逐行执行脚本,发现执行到 from CommandNotFound.db.creator import DbCreator 出现闪退。
观察系统日志:
|
1 2 3 4 |
$ sudo dmesg ........................... [14247.387532] python3[36129]: segfault at 0 ip 000071a2374c10f0 sp 00007ffc59f80c28 error 6 in libsqlite3.so.0.8.6[71a23744b000+10b000] likely on CPU 1 (core 1, socket 0) |
从系统日志上可以看到 libsqlite3 调用的数据库出现异常了,要么是数据库出问题,要么安装包出问题。更高概率是某个数据库文件出现问题了,那到底是哪个数据库文件呢?
我们不妨卸载重装一下 command-not-found,如下:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
$ sudo apt-get remove --purge command-not-found 正在读取软件包列表... 完成 正在分析软件包的依赖关系树... 完成 正在读取状态信息... 完成 下列软件包是自动安装的并且现在不需要了: python3-commandnotfound python3-gdbm 使用'sudo apt autoremove'来卸载它(它们)。 下列软件包将被【卸载】: command-not-found* 升级了 0 个软件包,新安装了 0 个软件包,要卸载 1 个软件包,有 0 个软件包未被升级。 解压缩后将会空出 29.7 kB 的空间。 您希望继续执行吗? [Y/n] (正在读取数据库 ... 系统当前共安装有 228019 个文件和目录。) 正在卸载 command-not-found (23.04.0) ... (正在读取数据库 ... 系统当前共安装有 228013 个文件和目录。) 正在清除 command-not-found (23.04.0) 的配置文件 ... dpkg: 警告: 卸载 command-not-found 时,目录 /var/lib/command-not-found 非空,因而不会删除该目录 错误:已到超时限制 |
结果问题依旧,那么是不是 /var/lib/command-not-found 这个目录下的数据库导致的呢?我们观察数据库文件:
|
1 2 |
$ ls /var/lib/command-not-found commands.db commands.db.metadata |
可以看到,这个目录下恰好有 libsqlite3 调用的数据库文件,我们删除这个目录,然后重启系统。
|
1 2 3 4 5 |
$ sudo apt-get reinstall command-not-found $ sudo rm -rf /var/lib/command-not-found/* $ sudo reboot |
结果出乎意外的修复了这个问题。