通用故障排除

来自 ArchWiki

本文介绍了一些通用故障排除的方法。对于特定于应用程序的问题,请参考该程序的特定 wiki 页面。

通用步骤

本文或章节需要扩充。

原因: 鉴于此页面的名称,应该在某处提及基本的“无需动脑筋”的解决方案,例如冷启动(可以明确指出基本塔式机与笔记本电脑的冷启动方式不同),更新到最新版本等……(在 Talk:General troubleshooting 中讨论)

始终阅读出现的任何错误消息至关重要。有时,例如对于图形应用程序,可能很难获得正确的错误消息。

  1. 在终端中运行应用程序,以便可以检查输出。
    1. 如果仍然没有足够的信息进行调试,请增加详细程度(通常是 --verbose/-v/-V--debug/-d)。
    2. 有时没有这样的参数,需要将其指定为应用程序配置文件中的指令。
    3. 应用程序也可能使用日志文件,这些文件通常位于 /var/log$HOME/.cache$HOME/.local
    4. 如果没有办法增加详细程度,始终可以运行 strace 和类似的工具。
  2. 检查 日志。错误也可能在日志中留下痕迹,特别是当它依赖于其他应用程序时。
    1. dmesg 从内核环形缓冲区读取。如果由于某种原因无法访问磁盘,这将非常有用,但这也可能导致日志不完整,因为内核环形缓冲区的大小不是无限的。如果可能,请使用 journalctl
    2. journalctldmesg 具有更多的 过滤选项,并且默认使用人类可读的时间戳。
  3. 始终建议检查相关的问题跟踪器,以查看是否存在已知问题以及已有的解决方案。
    1. 根据上游的选择,通常会有一个问题跟踪器,有时也会有论坛,甚至例如 IRC 频道。
    2. Arch Linux 错误跟踪器,它主要用于软件包错误。

额外支持

如果您需要任何额外支持,您可以在 论坛IRC 上提问。

注意: 仅为 Arch Linux 提供支持,而不为 基于 Arch 的发行版 提供支持。

当请求支持时,请发布完整的输出/日志,而不仅仅是你认为重要的部分。信息来源包括

  • 任何相关命令的完整输出 - 不要只选择你认为相关的部分。
  • systemd 的 日志
    • 对于更广泛的输出,请使用 systemd.log_level=debug 启动参数。这将产生大量的输出,因此只有在真正需要时才启用它。
    • 不要使用 -x 参数,因为这会不必要地使输出混乱并使其更难阅读。
    • 使用 -b,除非你需要以前启动的日志。不指定此项可能会导致非常大的粘贴,甚至可能太大而无法放入任何 pastebin。
  • 相关配置文件
  • 涉及的驱动程序
  • 涉及的软件包版本
  • 内核:journalctl -kdmesg(都需 root 权限)。
  • Xorg:取决于设置,此处使用的 显示管理器 也相关。
    • Xorg.log 可能位于以下几个位置之一:系统日志、/var/log/$HOME/.local/share/xorg/
    • 一些显示管理器(如 LightDM)也可能将 Xorg.log 放在其自己的日志目录中。
  • Pacman:如果最近的升级破坏了某些东西,请查看 /var/log/pacman.log
    • 使用 pacman--debug 参数可能很有用。

发布此信息的更好方法之一是使用 pastebin

然后将输出一个链接,您可以将其粘贴到论坛或 IRC。

此外,在提问之前,您可能希望查看 如何正确报告问题

启动问题

本文或章节需要扩充。

原因: 来自 Talk:Installation guide#Buggy graphics driver,也许可以添加一些关于在某些硬件上尝试 nomodeset 的内容?(在 Talk:General troubleshooting 中讨论)

在诊断启动问题时,了解启动失败的阶段非常重要。

  1. 固件 (UEFI 或 BIOS)
    1. 通常只有非常基本的调试工具。
    2. 确保 安全启动 已禁用。
  2. 启动引导器
    1. 此处最常见的操作之一是更改内核参数。
    2. 启动引导器阶段常见的启动问题可能是由 ACPI 引起的。
  3. initramfs
    1. 通常提供紧急 Shell。
    2. 根据选择的钩子,dmesg 或 日志 在其中可用。
  4. 实际系统
    1. 根据损坏的严重程度,简单调用 debug shell 可能就足够了。

如果任何阶段提供的调试工具不足以修复损坏的组件,请尝试使用例如 带有最新 Arch Linux ISO 的 USB 驱动器

控制台消息

启动过程后,屏幕被清除,并出现登录提示符,使用户无法读取 init 输出和错误消息。可以使用以下部分中概述的方法修改此默认行为。

请注意,无论选择哪个选项,内核消息都可以在启动后使用 journalctl -kdmesg 显示以供检查。要显示当前启动的所有日志,请使用 journalctl -b

流控制

这是适用于大多数终端模拟器(包括虚拟控制台 (VC))的基本管理

  • Ctrl+s 暂停输出。
  • Ctrl+q 恢复输出。

这不仅暂停输出,还暂停尝试打印到终端的程序,因为只要输出暂停,它们就会阻塞 write() 调用。如果您的 init 看起来已冻结,请确保系统控制台未暂停。

要查看已显示的错误消息,请参阅 Getty#Have boot messages stay on tty1

打印更多内核消息

大多数内核消息在启动期间被隐藏。您可以通过添加不同的内核参数来查看更多这些消息。最简单的参数是

  • debug,具有以下效果
    • 内核将提高其控制台 日志级别,以便内核日志缓冲区中的所有消息都将打印到控制台。 [1]
    • systemd 将提高其日志级别,以便它将记录调试消息,否则这些消息将不会在任何地方生成。 [2]
  • ignore_loglevel,它对内核具有与 debugloglevel=8 相同的效果(因为调试消息在 7 级),但阻止日志级别在启动后期被提高。

您可以添加的其他可能在某些情况下有用的参数是

  • earlyprintk=vga,keep 在启动过程的早期打印内核消息,以防内核在显示输出之前崩溃。对于 EFI 系统,您必须将 vga 更改为 efi
  • log_buf_len=16M 分配更大的(16 MiB)内核消息缓冲区,以确保调试输出不会被覆盖。

生成调试内核消息

#打印更多内核消息 指示如何将内核日志缓冲区打印到控制台,但该缓冲区本身不会包含任何已有的消息(除了调试 systemd 输出)。此标题讨论了从内核日志中获取更详细信息的方法。

动态调试

除非您执行以下操作之一,否则不会生成使用 pr_debug 或相关函数(如 dev_dbg()drm_dbg()bt_dev_dbg())打印的消息:

  • 修改内核源代码以在所需位置定义 DEBUG
  • 利用内核的 动态调试 功能来启用调试消息。

本节将讨论如何使用动态调试,如果您已经查看了内核日志,其中包含所有信息日志,并且想要从特定位置获得更多调试信息,这将非常有用。

首先,您必须运行使用设置了 CONFIG_DYNAMIC_DEBUG 内核配置选项编译的内核。对于 linux 而言,情况已经是这样,因此如果您使用该内核,则无需执行任何操作。

然后,您需要知道要从哪里查看调试消息。以下是一些选项:

  • 使用内核模块名称,如果问题似乎隔离在模块中。例如,要排除 Intel 显卡 的故障,您可能会关注 i915 DRM 内核模块
  • 使用内核中与您感兴趣的功能相对应的目录。您将需要查看(或在线浏览)内核 源代码以了解结构。例如,要检查所有 DRM 内核模块的调试消息,您可以使用路径 drivers/gpu/drm

使用该消息的“来源”,您必须提出一个动态调试查询,指示要启用哪些调试消息,格式为

match_type match_parameter flags

其中

  • match_type 是要进行的匹配类型。对应于前面给出的两个选项,这可以是 modulefile
  • match_parameter 是要监视的模块或文件路径。在后一种情况下,允许使用星号作为通配符。
  • flags 指示如何处理匹配项。这可以是 +p 以开始打印其消息,或 -p 以撤消该操作。

以下是一些查询示例:

  • module i915 +pi915 内核模块打印调试消息。
  • file drivers/gpu/drm/* +p 从 DRM 驱动程序打印调试消息。
  • file * +p 打印调试消息。

最后,要实际执行查询,您可以

  • 在运行时执行,通过运行
# echo "query" > /sys/kernel/debug/dynamic_debug/control
这假设 debugfs 已挂载在 /sys/kernel/debug/,您可以使用 mount 验证这一点。 [3]
  • 在启动时执行,通过添加 dyndbg="query" 内核参数

这只是对动态调试功能的极大简化概述;有关更多详细信息,请参阅 文档

子系统特定调试

还有许多单独的调试参数用于在特定子系统中启用调试,例如 bootmem_debugsched_debug。此外,initcall_debug 可用于调查启动冻结。(查找未返回的调用。)查看 内核参数文档 以获取具体信息。

netconsole

netconsole 是一个内核模块,它通过网络将所有内核日志消息(即 dmesg)发送到另一台计算机,而无需涉及用户空间(例如 syslogd)。名称“netconsole”用词不当,因为它实际上不是“控制台”,更像是远程日志记录服务。

它可以内置或作为模块使用。内置 netconsole 在 NIC 卡之后立即初始化,并将尽快启动指定的接口。该模块主要用于捕获来自无头机器的内核 panic 输出,或在用户空间不再起作用的其他情况下使用。

恢复 Shell

在启动过程的某个阶段获得交互式 shell 可以帮助您准确地查明问题发生的位置和原因。有几个内核参数可以做到这一点,但它们都启动一个普通的 shell,您可以 exit 以让内核恢复它正在执行的操作

  • rescue 在根文件系统重新挂载为读/写后不久启动 shell
  • emergency 更早地启动 shell,在大多数文件系统挂载之前
  • init=/bin/sh(作为最后的手段)将 init 程序更改为 root shell。rescueemergency 都依赖于 systemd,但这即使在 systemd 损坏的情况下也应该有效。

另一个选项是 systemd 的 debug-shell,它在 tty9 上添加一个 root shell(可以使用 Ctrl+Alt+F9 访问)。可以通过将 systemd.debug_shell 添加到 内核参数 或通过 启用 debug-shell.service 来启用它。

警告: 完成后请记住禁用该服务,以避免在每次启动时都留下 root shell 的安全风险。

调试内核模块

请参阅 Kernel modules#Obtaining information

调试硬件

调试冻结

不幸的是,冻结通常很难调试,其中一些冻结需要很长时间才能重现。有些类型的冻结比其他类型的更容易调试

  • 声音还在播放吗?如果是,则可能只是显示器冻结。这可能是视频驱动程序的问题。
  • 机器还在响应吗?如果切换到另一个 TTY 无效,请尝试 SSH
  • 磁盘活动 LED(如果存在)是否指示正在向磁盘写入大量内容?大量交换可能会暂时冻结系统。有关大写入时冻结的信息,请参阅 此 StackExchange 答案

如果其他方法都无效,请尝试干净关机。按一次电源按钮可能会解除系统冻结并显示经典的“关机屏幕”,其中显示所有正在停止的单元。或者,使用魔术 SysRq 键也可能有助于实现干净关机。这非常重要,因为 日志 可能包含机器冻结原因的提示。在不干净的关机时,日志可能不会写入磁盘。整个机器无响应的硬冻结更难调试,因为日志无法及时写入磁盘。

如果冻结不允许将任何内容写入磁盘,远程日志记录可能会有所帮助。一个粗略的远程日志记录解决方案(需要从另一台设备调用)可用于基本调试

$ ssh freezing_host journalctl -f

许多整个系统不再响应并需要强制关机的致命冻结可能与错误的固件、驱动程序或硬件有关。尝试不同的内核(请参阅 Kernel#Debugging regressions)甚至不同的 Linux 发行版或操作系统,更新固件和运行硬件诊断可能有助于找到问题。

提示: 建议尝试更新设备的固件,因为这些更新可能会修复奇怪的问题。

如果冻结不允许收集任何类型的日志或调试所需的其他信息,请尝试在 live 环境中重现冻结。如果需要图形环境才能重现冻结,或者冻结可以在 archiso 上重现,请使用不同发行版的 live 环境,最好是不要基于 Arch Linux 的发行版,以消除冻结与内核版本或补丁相关的可能性。如果冻结仍然发生在 live 环境中,则很可能与硬件有关。如果不再发生冻结,则有必要了解两个系统之间的差异。不同的配置、版本差异、内核参数和其他类似的更改可能已修复了冻结。

但是,闪烁的 Caps Lock LED 可能表示 内核 panic。某些设置可能在发生内核 panic 时不显示 TTY,这可能会造成混淆,并可能被解释为另一种冻结。

调试回归

警告: 这往往会导致 部分升级,在这种特定情况下,这是必要的恶。谨慎操作,并准备好 恢复系统的方法,以防这种情况阻止正常启动。

如果更新导致问题,但 降级 特定软件包可以解决问题,则很可能是 回归。如果在正常的完整系统升级后发生这种情况,请检查您的 pacman.log 以确定哪些软件包可能导致了问题。调试回归最重要的是检查问题是否已修复,因为这可以节省大量时间。为此,首先确保应用程序已完全更新(例如,确保应用程序的版本与 官方存储库 中的版本相同)。如果已经是,或者如果更新它没有解决问题,请尝试使用实际的最新版本,通常是 -git 版本,该版本可能已在 AUR 中打包。如果这解决了问题,并且带有修复程序的版本尚未在官方存储库中,请等待新版本到达存储库,然后切换回它。

如果问题仍然存在,请调试问题和/或 二分法 应用程序,并在上游错误跟踪器上报告错误,以便可以修复它。

注意: 在调试回归时,内核需要 略有不同的方法

内核升级后无法使用某些外围设备

这通常(但不限于)表现为

  • 新插入的 USB 设备在 dmesg 中显示,但不在 /dev/ 中,
  • 如果文件系统在内核更新之前未使用过,则无法挂载,
  • 如果笔记本电脑上的有线/无线连接在内核更新之前未使用过,则无法使用,
  • 使用 modprobe 加载内核包更新之前未使用的模块时,出现 FATAL: Module module not found in directory /lib/module/kernelversion

正如 System maintenance#Restart or reboot after upgrades 中部分介绍的那样,内核不会在您更新软件包时更新,而只会在您之后重新启动时更新。同时,位于 /usr/lib/modules/kernelversion/ 中的内核模块在安装新内核时会被 pacman 删除。正如 FS#16702 中解释的那样,这种方法避免了在系统上留下未由软件包管理器处理的文件,但会导致上述症状。要修复这些症状,请在更新内核后系统地重新启动。长期演进(尚未实施)将是使用版本化的内核软件包:主要障碍是如何处理不再需要的旧内核版本的删除。

另一个解决方案以 kernel-modules-hook 的形式提供,其中两个 pacman 钩子使用 rsync 在内核更新后将内核模块保留在文件系统上,并且 linux-modules-cleanup.service启用 后四周标记旧模块以供删除。

软件包管理

有关一般主题,请参阅 Pacman#Troubleshooting,有关 PGP 密钥的问题,请参阅 pacman/Package signing#Troubleshooting

修复损坏的系统

如果执行了 部分升级,请尝试更新您的整个系统。可能需要重新启动。

# pacman -Syu

如果您通常启动到 GUI 并且 GUI 失败,也许您可以按 Ctrl+Alt+F1Ctrl+Alt+F6 并进入一个工作正常的 tty 以运行 pacman

如果系统损坏到您无法运行 pacman请使用来自 USB 闪存驱动器、光盘或带有 PXE 的网络的每月 Arch ISO 启动。(不要遵循安装指南的其余部分。)

挂载您的根文件系统

# mount /dev/rootFileSystemDevice /mnt

挂载您单独创建的任何其他分区,并将前缀 /mnt 添加到所有分区,即

# mount /dev/bootDevice /mnt/boot

尝试在使用 chroot 时使用系统的 pacman

# arch-chroot /mnt
# pacman -Syu

如果失败,请退出 chroot,然后尝试

# pacman -Syu --sysroot /mnt

如果失败,请尝试

# pacman -Syu --root /mnt --cachedir /mnt/var/cache/pacman/pkg

fuser

本文或章节需要扩充。

原因: 需要更多关于其用法的信息(在 Talk:General troubleshooting 中讨论)

fuser 是一个命令行实用程序,用于识别使用文件、文件系统和 TCP/UDP 端口等资源的进程。

fuser 工具由 psmisc 软件包提供,该软件包应已作为 base 元软件包 的依赖项安装。有关详细信息,请参阅 fuser(1) 手册页。

会话权限

注意: 您必须使用 systemd 作为您的 init 系统,本地会话才能正常工作。[4] 这是 polkit 权限和各种设备 ACL 所必需的(参见 /usr/lib/udev/rules.d/70-uaccess.rules[5]

首先,确保您在 X 环境中拥有有效的本地会话

$ loginctl show-session $XDG_SESSION_ID

输出应包含 Remote=noActive=yes。 如果没有,请确保 X 运行在登录发生的同一 tty 上。 这是为了保留 logind 会话所必需的。

基本的 polkit 操作不需要进一步设置。 一些 polkit 操作需要进一步的身份验证,即使在本地会话中也是如此。 需要运行 polkit 身份验证代理才能使其工作。 有关此方面的更多信息,请参阅 polkit#Authentication agents

消息: "error while loading shared libraries"

如果在使用程序时,您收到类似于以下内容的错误

error while loading shared libraries: libusb-0.1.so.4: cannot open shared object file: No such file or directory

使用 pacmanpkgfile 搜索拥有缺失库的软件包

$ pacman -F libusb-0.1.so.4
extra/libusb-compat 0.1.5-1
    usr/lib/libusb-0.1.so.4

在这种情况下,libusb-compat软件包需要被安装。或者,请求库的程序可能需要按照 soname bump 进行重建。

该错误也可能意味着您用于安装程序的软件包未在其 PKGBUILD 中将库列为依赖项:如果是官方软件包,请 报告错误;如果是 AUR 软件包,请在其 AUR 网站页面上向维护者报告。

参见