Linux 内核是如何测试的?

发布于:2025-09-14 ⋅ 阅读:(20) ⋅ 点赞:(0)

大家好!我是大聪明-PLUS

你有没有想过 Linux 内核是如何测试的?一个由全球数千名程序员开发的、拥有数百万行代码的开源项目,其质量如何维护?

这并非易事。但这并不意味着不可能!

Linux 内核大约每 3 个月(10 到 12 周)发布一个新版本。在此期间,预留 2 周作为“合并窗口”,在此期间,所有已开发并获批准的版本都会合并到 Linus Torvalds 树(主线)中。其余 8 到 10 周的开发时间则用于修复错误和进行稳定化。

在稳定阶段,新的候选版本会发布(通常每周一次)。当 Linus Torvalds “感觉”代码“足够稳定”且上一个候选版本中的更改数量减少时,就会发布一个新的内核版本。

当我说 Linus Torvalds “觉得” 代码“足够稳定”时就会发布新版本时,我的意思是,Linux 内核开发过程中并没有什么非常正式的流程来发布新版本。没有一个神奇的工具来测试内核,也没有一个正式的测试计划来确保新内核版本能够正常工作。发布新版本的决定实际上是基于 Linux终身仁慈独裁者Linus Torvalds 的感受。

但这并不意味着没有对 Linux 内核进行测试。恰恰相反!

Linus Torvalds 本人在发布新版本内核时鼓励进行这些测试,有时他会在发布电子邮件的结尾加上“出去测试!”这句话。

内核开发过程也证明了对测试的高度重视,因为大约 20% 的开发过程(2 周)用于代码集成,而另外 80%(8 到 10 周)则专注于测试和错误修复。

但是,为了确保内核的高质量发布,我们不能仅仅依靠开发人员和用户的主动性。各种各样的工具都可以提供帮助,包括静态代码分析、测试自动化和持续集成工具。

那么让我们来谈谈有助于查找错误和测试 Linux 内核的最突出的工具?

静态代码分析

比在运行程序中寻找错误更好的方法是在运行之前找到并修复错误,对吧?这就是静态分析工具的工作。

静态分析工具能够在不运行程序的情况下分析源代码以查找问题。

有一些专注于 Linux 内核的静态分析工具可以帮助许多开发人员在开发过程中识别和修复问题。

Sparse是一个最初由 Linus Torvalds 编写并与 Linux 源代码集成的工具,旨在查找内核中可能存在的编码错误。该工具通过注释在源代码中执行多项语义验证。例如,如果内核代码尝试直接取消引用用户空间指针(标记为__user),该工具就会指出错误。

Smatch是一款专注于 Linux 内核的静态分析工具。该工具能够识别编程错误,例如访问空指针、缓冲区溢出、使用已释放的内存、死锁、使用未初始化的变量等等。

Coccinelle是一款非常有趣的工具,它能够识别源代码中的模式并自动进行修改。例如,假设您需要更改数百个设备驱动程序所使用的内核 API 函数的签名。无需手动打开每个驱动程序的源代码并进行修改,Coccinelle 就可以自动执行此过程。Coccinelle 已经识别出 Linux 内核中的数百个错误。例如,这个补丁就是由该工具自动生成的,用于修复内核中的一个内存泄漏错误。

除了静态分析工具外,目前还有几种测试自动化工具用于识别 Linux 内核中的错误和回归。

测试自动化工具可以在开发过程中为程序员提供很大帮助,避免执行重复任务,自动识别代码中可能存在的错误和回归,提高软件质量并节省开发人员的时间。

ktest是一个 Perl 脚本 ( ktest.pl ),位于 Linux 源代码的tools/testing/ktest/目录下,能够自动执行内核镜像的编译、部署和测试过程。该工具接收一个内核配置文件,根据此配置构建内核,然后将生成的镜像部署到远程机器上,以执行用户定义的某种自动化测试,例如等待来自串行控制台的登录消息。所有构建、部署和测试步骤均可配置。它是一个非常有用的内核自动化测试工具。LKML中的这条消息可供任何有兴趣深入了解该工具的人参考。

kselftest是一个测试框架,位于 Linux 源代码的tools/testing/selftests目录下,能够测试内核的特定部分。测试用例以 C 语言或 Shell 脚本编写,并在用户空间运行,用于测试内核的某些特定部分。它包含用于验证多个 Linux 内核子系统、库和 API 的测试,包括 cpufreq、gpio、networking、rtc、watchdog、cgroup、ftrace、futex、ipc 等。对于开发者和用户来说,kselftest 都是一个非常实用的工具,其文档可在内核源代码和此wiki页面中找到。

Linux测试项目( LTP) 提供了一套自动化测试,不仅可以验证 Linux 内核的功能,还可以验证操作系统的可靠性、稳健性和稳定性。该项目由 IBM、思科、富士通、SUSE 和 Red Hat 等公司开发和维护。测试使用 C 语言和 Shell 脚本编写,并直接在目标系统上运行。有关该项目的信息(包括源代码和文档)可在GitHub上找到。

Autotest是一个基于 GPL 许可的自动化测试框架,专注于 Linux 内核,由 Google、IBM 和 Red Hat 等多家机构开发和使用。它采用高度模块化的架构,包括用于运行测试的客户端、用于控制多个客户端的服务器以及用于触发测试和查看结果的 Web 界面。该工具的重点并非测试本身,而是提供一个基础架构来自动化执行其他项目实现的测试。例如,Autotest 使用了 Linux 测试项目 (Linux Test Project) 实现的测试用例。该项目的源代码及其文档可在GitHub上获取。

KUnit是Google的Brendan Higgins于2018年底在Linux内核邮件列表中提出的Linux 内核单元测试框架。据项目作者介绍,该框架的灵感来自其他单元测试工具,例如 JUnit (Java)、unittest.mock (Python) 和 Googletest/Googlemock (C++)。大多数测试自动化工具都需要运行内核的机器来运行测试,而 kunit 则不需要。它使用一种称为用户模式Linux的内核特性,这是一种特殊的架构,可以像运行另一个程序一样运行 Linux 内核。因此,无需在单独的机器上运行测试。KUnit 的文档可在Linux内核源代码中找到。

另一种非常常见的自动化测试技术称为模糊测试,主要用于识别安全问题。模糊测试工具能够为应用程序生成随机/无效条目,并监控结果以识别可能存在的问题,例如崩溃或资源泄漏。两个主要的 Linux 内核模糊测试工具是Trinity和Sykaller。还有一个名为 Syzbot 的自动化工具,它会在某些 Linux 内核树上持续运行 Syzkaller,并将发现的问题报告到此网站。

最后,还有几个为测试特定内核子系统而开发的工具,包括专注于内存管理的mmtests 、用于测试文件系统的xfstests和用于测试调度程序的hackbench。

许多此类测试工具用于持续集成项目,以识别和报告 Linux 内核开发过程中的错误。

持续集成

每天都有数百次提交到内核开发和生产仓库。这些提交可能会导致各种问题,包括回归、构建失败以及与其他分支和仓库的合并冲突。

在这种情况下,持续集成 (CI) 的实践可以提供帮助。CI 工具将集成开发人员每天完成的工作,实现测试自动化,并能够在生产环境出现 bug 之前就发现并修复 bug。

KernelCI是 Linux 基金会的一个项目,也是目前最完善的 Linux 内核自动化测试和持续集成工具。该工具由 Linaro 于 2014 年创建,并发布在kernelci.org上。它能够在多个内核开发树上执行自动构建测试,在大量硬件平台上启动已编译的内核,并执行一些自动化测试。测试结果发布在该项目的邮件列表和网站上。该工具的源代码托管在GitHub上。

另一个用于持续集成 Linux 内核的工具是0-Day测试服务。该工具由英特尔创建和维护,专注于 x86 架构,监控各种内核开发和生产树,自动执行构建、启动、功能和性能测试。检测到问题时,会向内核维护人员发送电子邮件。根据该项目网站的信息,它已经帮助识别了内核开发树中超过 40,000 个错误!

LKFT(Linux 内核功能测试)是Linaro推出的一款持续集成工具,它对多个内核开发树执行功能测试,以识别错误和回归问题。构建过程使用 OpenEmbedded 完成,并在 ARM 和 x86 平台(32 位和 64 位)上进行自动化测试。

Kerneltests项目创建于 2013 年,用于测试 Linux 内核的稳定版本。该工具会持续在所有架构上运行构建测试,并在 QEMU 中进行一些启动测试。

还有其他用于测试自动化和持续集成的工具,例如Fuego、LAVA和Beaker。一些维护 Linux 发行版的社区使用这些测试自动化工具来识别和报告内核问题。

那么,我们的系统中没有 bug 了吗?

当然不是。但正如我们所见,Linux 内核测试目前已有几个项目,从用户和开发者入手,使用静态代码分析、模糊测试、单元测试、测试自动化和持续集成等工具。这是社区为维护世界上最大的开源项目之一的质量而做出的持续合作。

但未来仍面临许多挑战。

尽管近年来测试覆盖率有所提升,但内核源代码库仍然非常庞大,并且随着每次发布都呈指数级增长,维护和提升测试覆盖率需要付出巨大的努力。另一个重大挑战是实现设备驱动程序和硬件平台测试的自动化,因为它们需要测试硬件。此外,工具之间也缺乏协作、互操作性和标准化。

所以,改进的空间总是存在的。这些挑战应该激励社区改进现有的工具和流程,开发新的技术和测试工具,并持续提升 Linux 内核的质量。