ChatGPT解决这个技术问题 Extra ChatGPT

Linux 内核是如何测试的?

Linux 内核开发人员如何在本地和提交代码后测试他们的代码?他们是否使用某种单元测试和构建自动化?测试计划?

youtube.com/watch?v=L2SED6sewRw,在某个地方,我记不清了,但我认为在 QA 部分正在讨论这个问题。
Anders 的链接很棒 - 顶级内核开发人员之一 Greg Kroah Hartman 的 Google 技术讲座。他验证了内核开发人员@adobriyan 下面给出的答案。 Greg 注意到内核的有趣之处 - 没有运行它就没有好的测试方法 - 难以进行单元测试等 - 许多排列。 “我们依靠开发社区进行测试。我们想要尽可能多的功能测试,以及性能测试。”直接指向测试讨论的链接是 youtube.com/…
随着虚拟机的普及,难道不能通过使用一堆配置排列构建内核并尝试在它们上启动来实现自动化吗?无论如何,它都不是“单元”测试,但它可以捕获错误。
@DanielKaplan:如果您假设大约有 1000 个主板,每个主板都有 10 个 CPU 中的一个,加上 1000 个 PCI 设备中的 3 个,以及 1000 个 USB 设备中的 3 个;并且内核有 1000 个不同的可能编译时间选项;那么您正在查看大约 1000*10*1000*999*9981000*999*998*1000 可能的排列来测试。如果您对每个排列进行 8 小时的预烧测试,并拥有一个由 100 台服务器组成的池来同时并行运行 400 台虚拟机;那么当你测试了百万分之一时,结果将全部过时,因为有人更改了代码,你必须重新开始。
好吧,在内核中进行一些单元测试仍然很好。内核的大部分部分都依赖于硬件这一事实并不意味着可测试的小部分不值得测试。内核重新实现了 libc 的大部分(因为它在内核空间中不可用),可以进行单元测试。某些模块中的某些功能也可以进行测试,如果是这种情况,我知道一些可以避免的微不足道的错误(仅在某些硬件上有效,但在部分代码中被隔离到足以进行测试)。

P
Peter Mortensen

Linux 内核非常重视社区测试。

通常,任何开发人员都会在提交之前测试他们自己的代码,而且他们通常会使用来自 Linus 的开发版本的内核,或者与他们的工作相关的项目的其他不稳定/开发树之一。这意味着他们经常同时测试他们的更改和其他人的更改。

正式测试计划的方式往往不多,但在将功能合并到上游树之前可能会要求进行额外的测试。

正如 Dean 指出的,还有一些自动化测试,linux test projectkernel autotest (good overview)。

开发人员通常还会编写自动化测试来测试他们的更改,但我不确定是否有(经常使用的)机制来集中收集这些临时测试。

当然,这在很大程度上取决于内核的哪个区域正在更改 - 您为新网络驱动程序所做的测试与更换核心调度算法时所做的测试完全不同。


+1,成功的一半只是没有破坏驾驶员所依赖的东西,因此 BKL 多年来的坚持。要考虑的另一件事是在许多不同的体系结构上测试许多子系统,这实际上只有在 Linux 收到的那种社区滥用、错误测试的情况下才可行。
P
Peter Mortensen

当然,内核本身及其部件在发布之前都会进行测试,但这些测试仅涵盖基本功能。有一些测试系统执行 Linux 内核的测试:

The Linux Test Project (LTP) 向开源社区提供测试套件,以验证 Linux 的可靠性和稳定性。 LTP 测试套件包含一组用于测试 Linux 内核和相关功能的工具。

Autotest——全自动测试框架。它主要设计用于测试 Linux 内核,尽管它可用于许多其他目的,例如验证新硬件、虚拟化测试和 Linux 平台下的其他一般用户空间程序测试。它是 GPL 下的一个开源项目,被许多组织使用和开发,包括 Google、IBM、Red Hat 和许多其他组织。

还有一些主要的 GNU/Linux 发行公司开发的认证系统。这些系统通常会检查完整的 GNU/Linux 发行版是否与硬件兼容。有 Novell、Red Hat、Oracle、Canonical 和 Google 开发的认证系统。

Linux内核也有动态分析系统:

Kmemleak 是一个包含在 Linux 内核中的内存泄漏检测器。它提供了一种以类似于跟踪垃圾收集器的方式检测可能的内核内存泄漏的方法,不同之处在于不释放孤立对象,而仅通过 /sys/kernel/debug/kmemleak 报告。

Kmemcheck 捕获对动态分配的内存的每次读取和写入(即,使用 kmalloc())。如果读取了以前未写入的内存地址,则会在内核日志中打印一条消息。它也是 Linux 内核的一部分。

故障注入框架(包含在 Linux 内核中)允许将错误和异常注入应用程序的逻辑,以实现更高的系统覆盖率和容错能力。


P
Peter Mortensen

Linux 内核开发人员如何在本地和提交代码后测试他们的代码?他们是否使用某种单元测试和构建自动化?

用经典的话来说,不。

例如,Ingo Molnar 正在运行以下工作负载:

用一组随机的配置选项构建一个新内核 启动到它去 1

每次构建失败、启动失败、错误或运行时警告都会得到处理。 24/7。乘以几格,可以发现不少问题。

测试计划?

不。

可能有一个误解,认为有一个中央测试设施,但没有。每个人都做他/她想做的事。


鉴于存在 thisthis 等网站,我也会质疑这个答案的有效性。
我认为 adobriyan 回答的核心是“有中央测试设施,没有”。差不多吧。然而,不同的小组进行不同级别的测试,这并不是说内核是完全未经测试的。
我认为 SUSE 和 RedHat 除了测试自己的内核外,还经常测试 vanilla。本身并没有中央测试,但仍然有一个测试正在进行——由 Linux 的主要用户进行。否则评论成立。如果它写得不那么讽刺,我什至会修改它。
Errr,你们都知道 Alexey Dobriyan 是 Linux 内核开发人员吗?
作为另一位内核开发人员,我必须说这是对这个问题最诚实的回答:内核没有经过经典意义上的测试,仅仅是因为这是不可能的。配置和硬件的组合比可用的开发人员测试时间更多。很少有人具备测试某些设备所需的技能,在某些情况下,很少有人真正拥有某些设备。
C
Ciro Santilli Путлер Капут 六四事

树内工具

在内核中找到测试工具的一个好方法是:

提供帮助并阅读所有目标

查看工具/测试

在 v4.0 中,这导致我:

工具/测试/自我测试下的 kselftest。使用 make kselftest 运行。必须已经在运行构建的内核。另见:文档/kselftest.txt,https://kselftest.wiki.kernel.org/

ktest 在工具/测试/ktest 下。另见:http://elinux.org/Ktest,http://www.slideshare.net/satorutakeuchi18/kernel-auto-testbyktest

make help 的静态分析器部分,其中包含以下目标: checkstack: Perl: what does checkstack.pl in linux source do? Coccinelle 的 coccicheck(由 askb 提及)

checkstack: Perl: linux 源代码中的 checkstack.pl 是做什么的?

Coccinelle 的 coccicheck(由 askb 提及)

内核 CI

https://kernelci.org/ 是一个旨在使内核测试更加自动化和可见的项目。

它似乎只做构建和启动测试(TODO 如何自动测试启动工作的源应该在 https://github.com/kernelci/)。

Linaro 似乎是该项目的主要维护者,来自许多大公司的贡献:https://kernelci.org/sponsors/

利纳罗熔岩

http://www.linaro.org/initiatives/lava/ 看起来像是一个专注于开发板启动和 Linux 内核的 CI 系统。

手臂丽莎

https://github.com/ARM-software/lisa

不确定它的详细功能,但它是由 ARM 和 Apache 授权的,因此可能值得一看。

演示:https://www.youtube.com/watch?v=yXZzzUEngiU

步进调试器

不是真正的单元测试,但一旦你的测试开始失败可能会有所帮助:

QEMU + GDB:https://stackoverflow.com/a/42316607/895245

KGDB:https://stackoverflow.com/a/44226360/895245

我自己的 QEMU + Buildroot + Python 设置

我还开始了一个专注于易于开发的设置,但最终我也添加了一些简单的测试功能:https://github.com/cirosantilli/linux-kernel-module-cheat/tree/8217e5508782827320209644dcbaf9a6b3141724#test-this-repo

我还没有详细分析所有其他设置,它们可能比我做的更多,但是我相信我的设置很容易快速上手,因为它有很多文档和自动化。


您能否也看看并可能为this做出贡献
@JhonnyS 感谢您的 ping。恐怕我对uboot不太熟悉,所以除了阅读源/ ping各自的上游之外我没有任何建议:-)这可能是相关的:titanwolf.org/Network/Articles/…
感谢您的参考。让我试试。
P
Peter Mortensen

自动化内核测试并不容易。大多数 Linux 开发人员自己进行测试,就像 adobriyan mentioned

但是,有一些东西有助于调试 Linux 内核:

kexec:一个系统调用,允许您将另一个内核放入内存并重新启动,而无需返回 BIOS,如果失败,则重新启动。

dmesg:绝对是查找有关内核启动期间发生的事情以及它是否有效/无效的信息的地方。

Kernel Instrumentation:除了 printk(和一个名为 'CONFIG_PRINTK_TIME' 的选项,它允许您查看(精确到微秒)内核何时输出什么),内核配置允许您打开许多跟踪器,使它们能够调试什么正在发生。

然后,开发人员通常会让其他人审查他们的补丁。一旦补丁在本地被审查并且不会干扰其他任何东西,并且补丁经过测试可以与来自 Linus 的最新内核一起工作而不会破坏任何东西,这些补丁就会被推送到上游。

Here's a nice video 详细说明补丁在集成到内核之前所经历的过程。


P
Peter Mortensen

除了其他答案外,本文更强调Linux内核的功能测试、硬件认证测试和性能测试。

很多测试实际上是通过脚本、静态代码分析工具、代码审查等进行的,这在捕捉错误方面非常有效,否则会破坏应用程序中的某些东西。

Sparse – 一种开源工具,旨在查找 Linux 内核中的故障。

Coccinelle 是另一个执行匹配和转换引擎的程序,它提供语言 SmPL(语义补丁语言)用于在 C 代码中指定所需的匹配和转换。

checkpatch.pl and other scripts - 编码风格问题可以在内核源代码树的 Documentation/CodingStyle 文件中找到。阅读时要记住的重要一点不是这种风格比任何其他风格都好,只是它是一致的。这有助于开发人员轻松查找和修复编码风格问题。内核源代码树中的脚本 scripts/checkpatch.pl 已为其开发。这个脚本可以很容易地指出问题,并且应该始终由开发人员在他们的更改上运行,而不是让审阅者在以后指出问题时浪费他们的时间。


P
Peter Mortensen

还有:

MMTests 是用于分析结果的基准和脚本的集合。

Trinity 是 Linux 系统调用模糊测试器。

此外,SourceForge 的 LTP 页面已经过时,该项目已移至 GitHub。


P
Peter Mortensen

我可以想象他们使用虚拟化来进行快速测试。它可能是 QEMUVirtualBoxXen,以及一些用于执行配置和自动化测试的脚本。

自动化测试可能是通过尝试许多随机配置或一些特定配置(如果他们正在处理特定问题)来完成的。 Linux 有很多低级工具(例如 dmesg)来监视和记录来自内核的调试数据,所以我想也可以使用它。


你绝对是对的。当我进行内核模块开发时,我严重依赖 VirtualBox + KGDB 来逐行跟踪内核执行。是的,gdb 看到整个内核逐行执行真的很酷。与著名内核开发人员 Valerie Aurora 相同,例如:youtube.com/watch?v=Tach2CheAc8。在视频中,您可以看到她如何使用 UserModeLinux 虚拟化来逐步执行内核。
P
Peter Mortensen

据我所知,英特尔运行/资助了一个自动性能回归检查工具(名为 lkp/0 day)。它将测试发送到邮件列表的每个有效补丁,并检查从不同的微基准测试(如 hackbench、fio、unixbench、netperf 等)更改的分数。

一旦出现性能回归/改进,相应的报告将直接发送给补丁作者和抄送相关维护者。


P
Pradeep Goswami

LTP 和 Memtests 通常是首选工具。


P
Peter Mortensen

adobriyan mentioned Ingo 的随机配置构建测试循环。现在,0-day 测试机器人(又名 kbuild 测试机器人)几乎涵盖了这一点。此处介绍了一篇关于基础架构的好文章:Kernel Build/boot testing

这种设置背后的想法是尽快通知开发人员,以便他们能够尽快纠正错误(在某些情况下,在补丁进入 Linus 的树之前,因为 kbuild 基础设施也会针对维护者的子系统树进行测试)。


P
Peter Mortensen

我已经完成了 Linux 内核编译并为 Android(Android 6.0 (Marshmallow) 和 Android 7.0 (Nougat))做了一些修改,其中我使用 Linux 版本 3。我在 Linux 上交叉编译了它系统,手动调试错误,然后在 Android 中运行其启动映像文件并检查它是否进入漏洞。如果它运行完美,则意味着它是根据系统要求完美编译的。

For MotoG kernel Compilation

注意:Linux内核会根据系统硬件的要求而变化


修订版 2 中更改的链接已完全损坏。意图是什么?请通过 editing (changing) your answer 回复,而不是在评论中(没有“编辑:”、“更新:”或类似内容 - 答案应该看起来好像是今天写的)。
在这种情况下,什么是“漏洞”?它与“loophole”不同吗? - “一种逃避的方法,尤其是规则或法律中的模棱两可或例外,可以利用以避免其影响。”。你能详细说明吗?在评论中可以。
P
Peter Mortensen

在贡献者提交补丁文件并提出合并请求后,Linux 看门人会通过集成和审查来检查补丁。一旦成功,他们会将补丁合并到相关分支并发布新版本。

Linux Test Project 是提供在应用补丁后针对内核运行的测试场景(测试用例)的主要来源。这可能需要大约 2 到 4 个小时,这取决于具体情况。

请注意选定内核的文件系统将被测试。示例:ext4 针对 ext3 生成不同的结果,依此类推。

内核测试程序。

从存储库(Linux Kernel Archives 或 GitHub)获取最新的内核源代码应用补丁文件(使用 diff 工具)构建新内核。针对 LTP(Linux 测试项目)中的测试过程进行测试