二分查找回归

本文档描述了如何使用 git bisect 来查找导致某些功能失效的源代码更改 -- 例如,在从 Linux 6.0 升级到 6.1 后,某些功能停止工作。

本文重点介绍该过程的要点。如果您是内核二分查找的新手,最好遵循 如何验证错误和二分查找回归:它从头到尾地描述了所有内容,同时涵盖了多个方面,甚至内核开发人员有时也会忘记。 这包括尽早检测到二分查找会浪费时间的情况,因为没有人会在意结果 -- 例如,因为问题发生在内核将其自身标记为“tainted”之后,发生在已放弃的版本中,已被修复,或者是由您或您的 Linux 发行版执行的 .config 更改引起的。

使用二分查找查找导致内核问题的更改

注意:以下过程假定您已为二分查找做好一切准备。 这包括拥有包含适当源代码的 Git 克隆,安装构建和安装内核所需的软件,以及存储在安全位置的 .config 文件(以下示例假定为“~/prepared_kernel_.config”)以用作每个二分查找步骤中的原始基本配置;理想情况下,您还想出了一种完全可靠且直接的方法来重现回归。

  • 准备工作:启动二分查找,并告诉 Git 您认为可以正常工作和已损坏的历史记录点,Git 将其称为“good”和“bad”

    git bisect start
    git bisect good v6.0
    git bisect bad v6.1
    

    除了像“v6.0”和“v6.1”这样的 Git 标签之外,您还可以指定提交 ID。

  1. 将您准备好的 .config 复制到构建目录中,并根据 Git 检出的用于测试的代码库的需求对其进行调整

    cp ~/prepared_kernel_.config .config
    make olddefconfig
    
  2. 现在构建、安装和启动内核。 这可能会由于不相关的原因而失败,例如,当在二分查找的当前阶段发生编译错误时,以后的更改会解决该错误。 在这种情况下,运行 git bisect skip 并返回到步骤 1。

  3. 检查刚刚构建的内核中回归的功能是否正常。

    如果它工作正常,请执行

    git bisect good
    

    如果它已损坏,请运行

    git bisect bad
    

    请注意,即使一次出错也会使剩余的二分查找完全偏离方向。 为了防止以后不得不重新开始,因此您需要确保告诉 Git 的内容是正确的; 因此,如果您的重现器不可靠,通常最好多花几分钟进行测试。

    发出这两个命令中的一个后,Git 通常会检出另一个二分查找点,并打印类似“Bisecting: 675 revisions left to test after this (roughly 10 steps)”的内容。 在这种情况下,返回到步骤 1。

    如果 Git 而是打印类似“cafecaca0c0dacafecaca0c0dacafecaca0c0da is the first bad commit”,则您已完成二分查找。 在这种情况下,请移至下面的下一点。 请注意,在显示该行后,Git 会立即显示有关罪魁祸首的一些详细信息,包括其补丁描述; 这很容易填满您的终端,因此您可能需要向上滚动才能看到提及罪魁祸首的提交 ID 的消息。

    如果您错过了 Git 的输出,您可以随时运行 git bisect log 来打印状态:它将显示剩余的步骤数或提及二分查找的结果。

  • 建议的补充任务:将二分查找日志和当前的 .config 文件放在一边,以用于错误报告; 此外,告诉 Git 将源代码重置为二分查找之前的状态

    git bisect log > ~/bisection-log
    cp .config ~/bisection-config-culprit
    git bisect reset
    
  • 推荐的可选任务:尝试在最新的代码库之上还原罪魁祸首,并检查这是否修复了您的错误; 如果是这种情况,它将验证二分查找,并使开发人员能够通过还原来解决回归。

    要尝试此操作,请更新您的克隆并检出最新的主线。 然后告诉 Git 通过指定其提交 ID 来还原更改

    git revert --no-edit cafec0cacaca0
    

    Git 可能会拒绝此操作,例如,当二分查找落在合并提交上时。 在这种情况下,放弃尝试。 如果 Git 无法自行还原罪魁祸首,因为以后的更改依赖于它,也执行相同的操作 -- 至少除非您二分查找了稳定或长期内核系列,在这种情况下,您需要检出其最新的代码库并在那里尝试还原。

    如果还原成功,请构建并测试另一个内核,以检查还原是否解决了您的回归。

这样,该过程就完成了。 现在按照 报告问题 中的描述报告回归。

二分查找 linux-next

如果您遇到仅发生在 linux-next 中的问题,请在 linux-next 分支“stable”和“master”之间进行二分查找。 以下命令将为您添加为名为“next”的远程的 linux-next 树启动该过程

git bisect start
git bisect good next/stable
git bisect bad next/master

“stable”分支指的是当前 linux-next 版本(在“master”分支中找到)所基于的 linux-mainline 的状态 -- 因此前者应该没有出现在 -next 中但未出现在 Linus 的树中的任何问题。

这将跨越广泛的更改进行二分查找,您可能在以前的 linux-next 版本中使用过其中的一些更改而没有问题。 可悲的是,没有简单的方法可以避免检查它们:从一个 linux-next 版本二分查找到更高版本(例如在“next-20241020”和“next-20241021”之间)是不可能的,因为它们没有共同的历史记录。

其他阅读材料